Merge "CTS test for PopupWindow transitions with no anchor view"
diff --git a/Android.mk b/Android.mk
index 2d9856b..1894043 100644
--- a/Android.mk
+++ b/Android.mk
@@ -17,12 +17,3 @@
include cts/CtsCoverage.mk
include $(call all-subdir-makefiles)
-
-# Have the default build also build the tools for CTS so it is possible
-# to build individual tests with mmm without doing extra targets first.
-files: \
- $(CTS_JAVA_TEST_SCANNER_DOCLET) \
- $(CTS_JAVA_TEST_SCANNER) \
- $(CTS_NATIVE_TEST_SCANNER) \
- $(CTS_XML_GENERATOR)
-
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index 6d3693f..0d56341 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -72,7 +72,6 @@
LOCAL_SRC_FILES := \
$(call java-files-in, src/com/android/cts/verifier) \
$(call java-files-in, src/com/android/cts/verifier/backup) \
- $(call all-java-files-under, src/android) \
$(call all-Iaidl-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 \
@@ -92,6 +91,7 @@
notification-bot := $(call intermediates-dir-for,APPS,NotificationBot)/package.apk
permission-app := $(call intermediates-dir-for,APPS,CtsPermissionApp)/package.apk
+usb-companion := $(call intermediates-dir-for,APPS,CtsVerifierUSBCompanion)/package.apk
# Builds and launches CTS Verifier on a device.
.PHONY: cts-verifier
@@ -130,20 +130,15 @@
# $(hide) $(ACP) -fp cts/apps/CtsVerifier/assets/scripts/execute_power_tests.py $@
cts : $(verifier-zip)
-ifeq ($(HOST_OS),linux)
-$(verifier-zip) : $(HOST_OUT)/bin/cts-usb-accessory
-endif
$(verifier-zip) : $(HOST_OUT)/CameraITS
$(verifier-zip) : $(notification-bot)
$(verifier-zip) : $(permission-app)
+$(verifier-zip) : $(usb-companion)
$(verifier-zip) : $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk | $(ACP)
$(hide) mkdir -p $(verifier-dir)
$(hide) $(ACP) -fp $< $(verifier-dir)/CtsVerifier.apk
$(ACP) -fp $(notification-bot) $(verifier-dir)/NotificationBot.apk
$(ACP) -fp $(permission-app) $(verifier-dir)/CtsPermissionApp.apk
-ifeq ($(HOST_OS),linux)
- $(hide) $(ACP) -fp $(HOST_OUT)/bin/cts-usb-accessory $(verifier-dir)/cts-usb-accessory
-endif
$(hide) $(ACP) -fpr $(HOST_OUT)/CameraITS $(verifier-dir)
$(hide) cd $(cts-dir) && zip -rq $(verifier-dir-name) $(verifier-dir-name)
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index d8297a1..3fa7fe6 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -1694,23 +1694,26 @@
<activity android:name=".usb.accessory.UsbAccessoryTestActivity"
android:label="@string/usb_accessory_test"
- android:configChanges="keyboardHidden|orientation|screenSize"
- android:launchMode="singleTop">
+ android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
- <intent-filter>
- <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
- </intent-filter>
- <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
- android:resource="@xml/accessory_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>
+ <activity android:name=".usb.accessory.AccessoryAttachmentHandler">
+ <intent-filter>
+ <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
+ </intent-filter>
+
+ <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
+ android:resource="@xml/accessory_filter" />
+ </activity>
+
<activity android:name=".usb.device.UsbDeviceTestActivity"
android:label="@string/usb_device_test"
android:configChanges="keyboardHidden|orientation|screenSize">
@@ -2139,7 +2142,7 @@
android:process=":projectionservice" />
<activity android:name=".managedprovisioning.DeviceOwnerNegativeTestActivity"
- android:label="@string/provisioning_device_owner">
+ android:label="@string/negative_device_owner">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.cts.intent.category.MANUAL_TEST" />
@@ -2150,6 +2153,14 @@
<activity android:name=".managedprovisioning.DeviceOwnerNegativeTestActivity$TrampolineActivity" />
+ <activity android:name=".managedprovisioning.EnterprisePrivacyInfoOnlyTestActivity"
+ android:label="@string/enterprise_privacy_test">
+ <intent-filter>
+ <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_ENTERPRISE_PRIVACY_INFO_ONLY" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".managedprovisioning.DeviceOwnerPositiveTestActivity"
android:label="@string/positive_device_owner">
<intent-filter>
@@ -2245,6 +2256,14 @@
</intent-filter>
</activity>
+ <activity android:name=".managedprovisioning.EnterprisePrivacyTestListActivity"
+ android:label="@string/enterprise_privacy_test">
+ <intent-filter>
+ <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_ENTERPRISE_PRIVACY" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
<activity android:name=".managedprovisioning.CommandReceiverActivity"
android:theme="@android:style/Theme.NoDisplay"
android:noHistory="true">
diff --git a/apps/CtsVerifier/res/drawable/ic_usb_48.xml b/apps/CtsVerifier/res/drawable/ic_usb_48.xml
new file mode 100644
index 0000000..eebb4fb
--- /dev/null
+++ b/apps/CtsVerifier/res/drawable/ic_usb_48.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="48dp"
+ android:height="48dp"
+ android:viewportWidth="48.0"
+ android:viewportHeight="48.0">
+ <path
+ android:pathData="M30,14v8h2v4h-6V10h4l-6,-8 -6,8h4v16h-6v-4.14c1.41,-0.73 2.4,-2.16 2.4,-3.86 0,-2.43 -1.97,-4.4 -4.4,-4.4 -2.43,0 -4.4,1.97 -4.4,4.4 0,1.7 0.99,3.13 2.4,3.86V26c0,2.21 1.79,4 4,4h6v6.1c-1.42,0.73 -2.4,2.19 -2.4,3.9 0,2.43 1.97,4.4 4.4,4.4 2.43,0 4.4,-1.97 4.4,-4.4 0,-1.71 -0.98,-3.17 -2.4,-3.9V30h6c2.21,0 4,-1.79 4,-4v-4h2v-8h-8z"
+ android:fillColor="#757575"/>
+</vector>
diff --git a/apps/CtsVerifier/res/layout-land/usb_main.xml b/apps/CtsVerifier/res/layout-land/usb_main.xml
deleted file mode 100644
index 139b54b..0000000
--- a/apps/CtsVerifier/res/layout-land/usb_main.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- <LinearLayout android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- >
- <LinearLayout android:orientation="vertical"
- android:layout_width="1px"
- android:layout_height="match_parent"
- android:layout_weight="1"
- >
- <TextView android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/usb_sent_messages"
- style="?android:attr/listSeparatorTextViewStyle"
- />
- <FrameLayout android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- >
- <ListView android:id="@+id/usb_sent_messages"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- <TextView android:id="@+id/usb_empty_sent_messages"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:text="@string/usb_no_messages"
- android:visibility="gone"
- />
- </FrameLayout>
- </LinearLayout>
- <include layout="@layout/vertical_divider" />
- <LinearLayout android:orientation="vertical"
- android:layout_width="1px"
- android:layout_height="match_parent"
- android:layout_weight="1"
- >
- <TextView android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/usb_received_messages"
- style="?android:attr/listSeparatorTextViewStyle"
- />
- <FrameLayout android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- >
- <ListView android:id="@+id/usb_received_messages"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- <TextView android:id="@+id/usb_empty_received_messages"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:text="@string/usb_no_messages"
- android:visibility="gone"
- />
- </FrameLayout>
- </LinearLayout>
- </LinearLayout>
-
- <include layout="@layout/pass_fail_buttons" />
-
-</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/enterprise_privacy_negative_test.xml b/apps/CtsVerifier/res/layout/enterprise_privacy_negative_test.xml
new file mode 100644
index 0000000..a5c531b
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/enterprise_privacy_negative_test.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ style="@style/RootLayoutPadding">
+
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:fillViewport="true">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <TextView android:id="@+id/info"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:textSize="18sp"
+ android:padding="5dp" />
+
+ <include layout="@layout/pass_fail_buttons"/>
+ </LinearLayout>
+ </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/pwa_widgets.xml b/apps/CtsVerifier/res/layout/pwa_widgets.xml
index e5ebddb..cb611b9 100644
--- a/apps/CtsVerifier/res/layout/pwa_widgets.xml
+++ b/apps/CtsVerifier/res/layout/pwa_widgets.xml
@@ -12,19 +12,16 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
- <TextureView
- android:id="@+id/texture_view"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
<LinearLayout
+ android:id="@+id/test_controls"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:layout_gravity="top">
<LinearLayout
android:layout_width="match_parent"
@@ -55,4 +52,10 @@
</LinearLayout>
</LinearLayout>
-</LinearLayout>
+ <TextureView
+ android:id="@+id/texture_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_below="@id/test_controls" />
+
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/usb_main.xml b/apps/CtsVerifier/res/layout/usb_main.xml
index 5c16612..d693ae5 100644
--- a/apps/CtsVerifier/res/layout/usb_main.xml
+++ b/apps/CtsVerifier/res/layout/usb_main.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!-- Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,55 +14,40 @@
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- >
- <TextView android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/usb_sent_messages"
- style="?android:attr/listSeparatorTextViewStyle"
- />
- <FrameLayout android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- >
- <ListView android:id="@+id/usb_sent_messages"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- <TextView android:id="@+id/usb_empty_sent_messages"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:text="@string/usb_no_messages"
- android:visibility="gone"
- />
- </FrameLayout>
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
- <TextView android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/usb_received_messages"
- style="?android:attr/listSeparatorTextViewStyle"
- />
- <FrameLayout android:orientation="vertical"
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <ImageView android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:src="@drawable/ic_usb_48"
+ android:tint="@color/primary"
+ android:scaleType="fitCenter"
+ android:layout_marginBottom="16dp" />
+
+ <ProgressBar android:id="@+id/progress_bar"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- >
- <ListView android:id="@+id/usb_received_messages"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp"
+ android:visibility="gone" />
+
+ <ScrollView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1">
+
+ <TextView android:id="@+id/status"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- />
- <TextView android:id="@+id/usb_empty_received_messages"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center"
- android:text="@string/usb_no_messages"
- android:visibility="gone"
- />
- </FrameLayout>
+ android:layout_height="wrap_content" />
+
+ </ScrollView>
+
+ </LinearLayout>
<include layout="@layout/pass_fail_buttons" />
diff --git a/apps/CtsVerifier/res/layout/usb_message_row.xml b/apps/CtsVerifier/res/layout/usb_message_row.xml
deleted file mode 100644
index 3bb228a..0000000
--- a/apps/CtsVerifier/res/layout/usb_message_row.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="@style/MessageRow"
- />
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 64b7cb0..98543a2 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -1070,35 +1070,29 @@
<!-- Strings for USB accessory test activity -->
<string name="usb_accessory_test">USB Accessory Test</string>
- <string name="sensor_power_test">Sensor Power Test</string>
<string name="usb_accessory_test_info">
- 1. Connect your Android device to a computer and ensure that the connection is set
- to charging only from the Android device.
- \n\n2.Run the \'cts-usb-accessory\' program included with the CTS Verifier bundle.
- \n\n3. If you have not started the CTS Verifier, press \'OK\' when asked to open the CTS
- Verifier when the accessory is connected. \n\nIf you are already in this test,
- then you can press \'Cancel\' but press \'OK\' in the next dialog asking whether to allow
- CTS Verifier to access the accessory.
- \n\n4. You should see the accessory and the CTS Verifier display a series of messages
- which indicates that the accessory support is working properly, and then you will
- be presented with more instructions.
+ 1. Install the Cts Verifier USB Companion app on a separate helper device.
+ \n\n2. Start the accessory test companion in the Cts Verifier USB Companion.
+ \n\n3. Connect the two devices. If using a OTG adapter make sure the adapter is directly connected to the helper device. If using an Type-C cable make sure that the helper device is set as "supply power to the attached device".
+ \n\n4. Confirm access to the USB device on the helper device.
+ \n\n5. Confirm access to the USB accessory on this device
+ \n\n6. Confirm access to the USB device on the helper again.
+ \n\n7. Test will run and complete automatically in a less than 30 seconds.
+ \n\n8. Cancel all further dialogs on this device
</string>
- <string name="usb_not_available_title">USB accessory feature is not available?</string>
- <string name="usb_not_available_message">If your device is supposed to support USB accessories, your API implementation is not behaving correctly!</string>
- <string name="usb_received_messages">Received Messages</string>
- <string name="usb_reconnect_title">Disconnect and Reconnect</string>
- <string name="usb_disconnect_message">Please disconnect the Android device and the computer.</string>
- <string name="usb_connect_message">Please connect the Android device and the computer. Do not interact with the device until prompted.</string>
- <string name="usb_reconnect_timeout">Test failed because reconnect timed out. You can interact with the device again.</string>
- <string name="usb_reconnect_abort">Abort Test</string>
- <string name="usb_wait_for_done">Could not find USB accessory. Try waiting longer.</string>
- <string name="usb_sent_messages">Sent Messages</string>
- <string name="usb_no_messages">No messages</string>
- <string name="usb_message_thread_started">Starting message processing...</string>
- <string name="usb_message_thread_exception">Exception occurred while processing a message...</string>
- <string name="usb_message_thread_ended">Stopping message processing...</string>
- <string name="usb_test_passed">Test passed, pass button enabled! You can interact with the device again.</string>
- <string name="usb_file_descriptor_error">Could not open file descriptor for USB accessory... try reconnecting and restarting the accessory?</string>
+ <string name="usb_accessory_test_step1">
+ In this specific order:
+ \n1. Install the Cts Verifier USB Companion app on a separate helper device.
+ \n2. Start the accessory test companion in the Cts Verifier USB Companion.
+ \n3. Connect the two devices. If using a OTG adapter make sure the adapter is directly connected to the helper device. If using an Type-C cable make sure that the helper device is set as "supply power to the attached device".
+ \n4. Confirm access to the USB device on the helper device. Only confirm once.
+ \n5. Confirm access to the USB accessory on this device.
+ \n6. Confirm access to the USB device on the helper device again.
+ \n\nResult: A progress indicator should appear or test will finish.
+ </string>
+ <string name="usb_accessory_test_step2">
+ Test is running and will complete automatically in less than 30 seconds.
+ </string>
<!-- String for the USB device test activity -->
<string name="usb_device_test">USB Device Test</string>
@@ -1107,10 +1101,29 @@
\n\n2. Start the device test companion in the Cts Verifier USB Companion.
\n\n3. Connect the two devices. If using a OTG adapter make sure the adapter is directly connected to this device. If using an Type-C cable make sure that this device is set as "supply power to the attached device".
\n\n4. Confirm access to the USB device on this device.
- \n\n5. Confirm access to the USB accessory on the helper device
+ \n\n5. Confirm access to the USB accessory on the helper device.
\n\n6. Confirm access to the USB device on this device again.
- \n\n7. Test will run and complete automatically in a few seconds
- \n\n8. Cancel all further dialogs on the helper device
+ \n\n7. Test will run and complete automatically in less than 30 seconds.
+ \n\n8. Cancel all further dialogs on the helper device.
+ </string>
+ <string name="usb_device_test_step1">
+ In this specific order:
+ \n1. Install the Cts Verifier USB Companion app on a separate helper device.
+ \n2. Start the device test companion in the Cts Verifier USB Companion.
+ \n3. Connect the two devices. If using a OTG adapter make sure the adapter is directly connected to this device. If using an Type-C cable make sure that this device is set as "supply power to the attached device".
+ \n\nResult: A dialog should show up on this device asking for access to a USB device.
+ </string>
+ <string name="usb_device_test_step2">
+ Confirm access to the USB device on this device.
+ \n\nResult: Dialogs should show up on this device and on the helper device asking for access to a USB device/accessory.
+ </string>
+ <string name="usb_device_test_step3">
+ 1. Confirm access to the USB accessory on the helper device.
+ \n2. Confirm access to the USB device on this device again.
+ \n\nResult: A progress indicator should appear or test will finish.
+ </string>
+ <string name="usb_device_test_step4">
+ Test is running and will complete automatically in a less than 30 seconds.
</string>
<string name="usb_device_unexpected">Usb companion device is not as expected %1$s. Please retry test.</string>
@@ -1222,15 +1235,15 @@
<string name="p2p_go_neg_requester_info">
Go to the Wi-Fi settings and forget all remembered networks. Then
start the \"GO Negotiation Responder Test\" on the other device.
- Then run each test individually by clicking on it\'s name.</string>
+ Then run each test individually by clicking on its name.</string>
<string name="p2p_join_go_info">
Go to the Wi-Fi settings and forget all remembered networks. Then
start the \"Group Owner Test\" on the other device.
- Then run each test individually by clicking on it\'s name.</string>
+ Then run each test individually by clicking on its name.</string>
<string name="p2p_service_discovery_requester_info">
Go to the Wi-Fi settings and forget all remembered networks. Then
start the \"Service Discovery Responder Test\" on the other device.
- Then run each test individually by clicking on it\'s name.</string>
+ Then run each test individually by clicking on its name.</string>
<string name="p2p_not_enabled">Wi-Fi is not enabled</string>
<string name="p2p_not_enabled_message">These tests require Wi-Fi to be enabled.
@@ -1614,7 +1627,7 @@
<string name="provisioning_byod_capture_media_error">Error while capturing media from managed profile.</string>
<string name="provisioning_byod_capture_image_error">Error while capturing image from managed profile.</string>
- <string name="provisioning_byod_auth_bound_key">Autentication-boud keys</string>
+ <string name="provisioning_byod_auth_bound_key">Authentication-bound keys</string>
<string name="provisioning_byod_auth_bound_key_info">
This test verifies keystore cryptographic keys can be bound to device credentials.
These keys should only be available if there was a recent enough authentication.
@@ -1631,7 +1644,7 @@
<string name="provisioning_byod_auth_bound_key_set_up">Set up</string>
<string name="provisioning_byod_lockscreen_bound_key">Lockscreen-bound key test</string>
<string name="provisioning_byod_fingerprint_bound_key">Fingerprint-bound key test</string>
- <string name="provisioning_byod_vpn">Vpn test</string>
+ <string name="provisioning_byod_vpn">VPN test</string>
<string name="provisioning_byod_select_work_challenge">Select work lock test</string>
<string name="provisioning_byod_select_work_challenge_description">
This test verifies that a work lock can be chosen.\n
@@ -2157,9 +2170,9 @@
</string>
<string name="provisioning_byod_turn_off_work">Turn off work mode</string>
- <string name="provisioning_byod_turn_off_work_info">This test verifes device behaviours when turning off work mode.</string>
+ <string name="provisioning_byod_turn_off_work_info">This test verifies device behaviors when turning off work mode.</string>
<string name="provisioning_byod_turn_off_work_instructions">
- This test verifies the device behaviour when work profile is turned off.\n
+ This test verifies the device behavior when work profile is turned off.\n
Please exercise the following tests in sequence.\n
The button below can be used to open the Settings page where you can toggle work mode.
</string>
@@ -2230,14 +2243,32 @@
2. Lock and unlock the screen to verify that the personal side password was set correctly.\n
</string>
- <!-- Strings for DeviceOwnerProvisioningTest -->
- <string name="provisioning_device_owner">Device Owner Provisioning</string>
- <string name="device_owner_provisioning_tests">Device Owner provisioning tests</string>
- <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">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>
+ <!-- Strings for DeviceOwnerNegativeTestActivity -->
+ <string name="negative_device_owner">No Device Owner Tests</string>
+ <string name="device_owner_negative_category">No Device Owner Tests</string>
+ <string name="device_owner_provisioning_negative">Device owner provisioning</string>
+ <string name="device_owner_provisioning_negative_info">The device owner provisioning test verifies that setting up a corporate owned device can only be done on a factory reset device.\n\nPlease 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>
+ <string name="enterprise_privacy_quick_settings_negative">Quick settings disclosure</string>
+ <string name="enterprise_privacy_quick_settings_negative_info">
+ Please do the following:\n
+ 1) Open and fully expand Quick Settings.\n
+ 2) Verify that at the bottom of Quick Settings, you are not told the device is managed.\n
+ 3) Close Quick Settings.
+ </string>
+ <string name="enterprise_privacy_keyguard_negative">Keyguard disclosure</string>
+ <string name="enterprise_privacy_keyguard_negative_info">
+ Please do the following:\n
+ 1) Press the Go button to open Settings.\n
+ 2) Navigate to \"Security\" > \"Screen lock\" and select the first screen lock type that is not \"None\".\n
+ 3) Use the Back button to return to this page.\n
+ 4) Lock the device.\n
+ 5) Verify that on the lock screen, you are not told the device is managed.\n
+ 6) Unlock the device.\n
+ 7) Repeat steps (1) through (6) for each screen lock type other than \"None\".
+ </string>
+
+ <!-- Strings for DeviceOwnerPositiveTestActivity -->
<string name="positive_device_owner">Device Owner Tests</string>
<string name="device_owner_positive_tests">Device Owner positive tests</string>
<string name="device_owner_positive_tests_instructions">
@@ -2339,8 +2370,8 @@
<string name="device_profile_owner_permission_lockdown_test">Permissions lockdown</string>
<string name="device_profile_owner_permission_lockdown_test_instructions">
Select each of the three grant states for the permission shown below in turn.\n
- Now open application settings, select Permissions, and verify if the following behaviour is observed.\n
- <b>Allow:</b> Permission is granted to the app and cannot be changed through the settings UI. Trying to change it triggers a support message.\n
+ Now open application settings, select Permissions, and verify if the following behavior is observed.\n
+ <b>Grant:</b> Permission is granted to the app and cannot be changed through the settings UI. Trying to change it triggers a support message.\n
<b>Let user decide:</b> Permission state can be changed through the settings UI.\n
<b>Deny:</b> Permission is denied to the app and cannot be changed through the settings UI. Trying to change it triggers a support message.\n
Please mark the test accordingly.
@@ -2442,7 +2473,7 @@
<string name="device_owner_settings_go">Go</string>
<string name="device_owner_vpn_connection">
- Vpn connection has been established.\n
+ VPN connection has been established.\n
This is not as expected.\n
Mark this test as failed.\n
</string>
@@ -2457,19 +2488,19 @@
Mark this test as passed.\n
</string>
<string name="device_owner_vpn_test">Check VPN</string>
- <string name="device_owner_vpn_info_default">Vpn test message</string>
+ <string name="device_owner_vpn_info_default">VPN test message</string>
<string name="device_owner_disallow_config_vpn">Disallow configuring VPN</string>
<string name="device_owner_disallow_config_vpn_info">
Please press the Set VPN restriction button to set the VPN restriction.
Perform tests in order. Mark test as passed if both test cases pass\n\n
- 1. Press Go to open the Vpn settings page.\n
+ 1. Press Go to open the VPN settings page.\n
Confirm that:\n
- You cannot add a new VPN network.\n
- You cannot edit, add or remove any existing VPNs.\n
- Trying to perform any of the above actions will trigger a support message.\n\n
- 2. Press Check VPN to check programmatic Vpn test.\n
- - Check Vpn setup is not allowed\n
+ 2. Press Check VPN to check programmatic VPN test.\n
+ - Check VPN setup is not allowed\n
- If prompted to allow a VPN connection, press OK.\n\n
Use the Back button to return to this page.
</string>
@@ -2684,18 +2715,102 @@
Check that \'Dummy Input method\' is not enabled in Settings and disallow \'Dummy Input method\' from permitted input methods by turning on the switch below.
</string>
<string name="set_permitted_input_methods_action">
- Enabling \'Dummy Input Method\' in the list of accessibility services
+ Enabling \'Dummy Input method\' in the list of accessibility services
</string>
<string name="set_permitted_input_methods_widget_label">
Allow only system input methods:
</string>
+ <!-- Strings used for enterprise privacy tests -->
+ <string name="enterprise_privacy_test">Privacy info test</string>
+ <string name="enterprise_privacy_page">Privacy info page</string>
+ <string name="enterprise_privacy_page_info">
+ Please press the Go button to open Settings. Verify that:\n
+ 1) There is an entry for device privacy.\n
+ 2) Tapping that entry opens a screen in which you are told your organization can:\n
+ 3) Change settings on this device.\n
+ 4) See data associated with your work account.\n
+ 5) See the list of all apps on your device.\n
+ 6) See usage of each app on your device.\n
+ \n
+ Use the Back button to return to this page.
+ </string>
+ <string name="enterprise_privacy_open_settings">Open Settings</string>
+ <string name="enterprise_privacy_network_logging">Retrieve traffic logs</string>
+ <string name="enterprise_privacy_network_logging_info">
+ Please do the following:\n
+ 1) Press the Retrieve Traffic Logs button and record the time at which you did this.\n
+ 2) Wait one minute.\n
+ 3) Press the Open Settings button.\n
+ 4) In the screen that opens, verify that you are told traffic logs were last retrieved at the time you pressed the Retrieve Traffic Logs button in step (1).\n
+ \n
+ Use the Back button to return to this page.
+ </string>
+ <string name="enterprise_privacy_retrieve_network_logs">Retrieve Traffic Logs</string>
+ <string name="enterprise_privacy_bug_report">Request bug report</string>
+ <string name="enterprise_privacy_bug_report_info">
+ Please do the following:\n
+ 1) Press the Request Bug Report button and record the time at which you did this.\n
+ 2) Wait one minute.\n
+ 3) Press the Open Settings button.\n
+ 4) In the screen that opens, verify that you are told a bug report was last requested at the time you pressed the Request Bug Report button in step (1).\n
+ \n
+ Use the Back button to return to this page.
+ </string>
+ <string name="enterprise_privacy_request_bug_report">Request Bug Report</string>
+ <string name="enterprise_privacy_security_logging">Retrieve security logs</string>
+ <string name="enterprise_privacy_security_logging_info">
+ Please do the following:\n
+ 1) Press the Retrieve Security Logs button and record the time at which you did this.\n
+ 2) Wait one minute.\n
+ 3) Press the Open Settings button.\n
+ 4) In the screen that opens, verify that you are told security logs were last retrieved at the time you pressed the Retrieve Security Logs button in step (1).\n
+ \n
+ Use the Back button to return to this page.
+ </string>
+ <string name="enterprise_privacy_retrieve_security_logs">Retrieve Security Logs</string>
+ <string name="enterprise_privacy_clear_organization">Clear Org</string>
+ <string name="enterprise_privacy_set_organization">Set Org</string>
+ <string name="enterprise_privacy_quick_settings">Quick settings disclosure</string>
+ <string name="enterprise_privacy_quick_settings_info">
+ Please do the following:\n
+ 1) Press the Clear Org button.\n
+ 2) Open and fully expand Quick Settings.\n
+ 3) Verify that at the bottom of Quick Settings, you are told the device is managed.\n
+ 4) Close Quick Settings.\n
+ 5) Press the Set Org button.\n
+ 6) Open and fully expand Quick Settings.\n
+ 7) Verify that at the bottom of Quick Settings, you are told the device is managed by \"Foo, Inc.\".\n
+ 8) Tap on the information.\n
+ 9) Verify that a dialog informing you about device monitoring opens.\n
+ 10) Tap the \"Learn more\" link.\n
+ 11) Verify that a screen informing you what your managing organization can do is shown.\n
+ \n
+ Use the Back button to return to this page.
+ </string>
+ <string name="enterprise_privacy_keyguard">Keyguard disclosure</string>
+ <string name="enterprise_privacy_keyguard_info">
+ Please do the following:\n
+ 1) Press the Open Settings button to open Settings.\n
+ 2) Navigate to \"Security\" > \"Screen lock\" and select the first screen lock type that is not \"None\".\n
+ 3) Use the Back button to return to this page.\n
+ 4) Press the Clear Org button.\n
+ 5) Lock the device.\n
+ 6) Verify that on the lock screen, you are told the device is managed.\n
+ 7) Unlock the device.\n
+ 8) Press the Set Org button.\n
+ 9) Lock the device.\n
+ 10) Verify that on the lock screen, you are told the device is managed by \"Foo, Inc.\".\n
+ 11) Unlock the device.\n
+ 12) Repeat steps (1) through (11) for each screen lock type other than \"None\".
+ </string>
+
<!-- Strings for JobScheduler Tests -->
<string name="js_test_description">This test is mostly automated, but requires some user interaction. You can pass this test once the list items below are checked.</string>
<string name="js_idle_test">Idle Mode Constraints</string>
<string name="js_start_test_text">Start test</string>
- <string name="js_idle_instructions">Verify the behaviour of the JobScheduler API for when the device is in idle mode. Simply follow the on-screen instructions.</string>
+ <string name="js_idle_instructions">Verify the behavior of the JobScheduler API for when the device is in idle mode. Simply follow the on-screen instructions.</string>
<string name="js_idle_description_1">Turn the screen off and then back on in order to begin.</string>
<string name="js_idle_continue_instruction">
Switch off screen and wait for it to turn on to continue.
@@ -2704,16 +2819,16 @@
<string name="js_idle_item_idle_on">Idle job does execute when device is forced into idle.</string>
<string name="js_charging_test">Charging Constraints</string>
- <string name="js_charging_instructions">Verify the behaviour of the JobScheduler API for when the device is on power and unplugged from power. Simply follow the on-screen instructions.</string>
+ <string name="js_charging_instructions">Verify the behavior of the JobScheduler API for when the device is on power and unplugged from power. Simply follow the on-screen instructions.</string>
<string name="js_charging_description_1">Plug in the charger if it isn\'t already plugged in.</string>
<string name="js_charging_off_test">Device not charging will not execute a job with a charging constraint.</string>
<string name="js_charging_on_test">Device when charging will execute a job with a charging constraint.</string>
<string name="js_charging_description_2">After the above test has passed, remove the charger to continue. If the above failed, you can simply fail this test.</string>
- <string name="js_charging_description_3">Device is plugged in. Please wait while it get\s into stable charging state.</string>
+ <string name="js_charging_description_3">Device is plugged in. Please wait while it gets into stable charging state.</string>
<string name="js_charging_description_4">There seems to be a problem with your charger. Pleasy try again.</string>
<string name="js_connectivity_test">Connectivity Constraints</string>
- <string name="js_connectivity_instructions">Verify the behaviour of the JobScheduler API for when the device has no access to data connectivity. Simply follow the on-screen instructions.</string>
+ <string name="js_connectivity_instructions">Verify the behavior of the JobScheduler API for when the device has no access to data connectivity. Simply follow the on-screen instructions.</string>
<string name="js_connectivity_description_1">Disable WiFi and Cellular data to begin.</string>
<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>
@@ -3100,9 +3215,9 @@
turquoise action button at each one. You need to reach each waypoint in 20 seconds. While
you are on your way to the waypoints, the camera preview will rotate. You will need to
rotate the device to match the rotation of the camera preview. A box will be shown to help
- you. It shows the device\'s current rotation and will change colour based on whether you are
+ you. It shows the device\'s current rotation and will change color based on whether you are
close enough to the required rotation. Red if you are failing, green if you are passing.
- When you have reached the next waypoint, the device can be returned to it\'s original
+ When you have reached the next waypoint, the device can be returned to its original
rotation.
</string>
<string name="last">Go back to the first waypoint</string>
@@ -3118,7 +3233,7 @@
<string name="results">Results</string>
<string name="overall_instructions">These tests are designed to verify the correctness and
accuracy of a 6DoF enabled device. There will be 3 phases to these tests, each testing a
- different part of 6DOF functionality.
+ different part of 6DoF functionality.
</string>
<string name="phase1_description">This first test will test the accuracy of the device. It will
ask you to mark out 4 waypoints and then return to the original waypoint to complete the
@@ -3130,10 +3245,10 @@
same 4 waypoints as before, you will need to do a lap, reaching each waypoint in the
allotted time.\nWhile you are on your way to the waypoints, the camera preview will rotate.
You will need to rotate the device to match the rotation of the camera preview. A box will
- be shown to help you. It shows the device\'s current rotation and will change colour based
+ be shown to help you. It shows the device\'s current rotation and will change color based
on whether you are close enough to the required rotation. Red if you are failing, green if
you are passing. When you have reached the next waypoint, the device can be returned to
- it\'s original rotation.
+ its original rotation.
</string>
<string name="phase3_description">Now we will test the AR capability of the device. Again, you
will need to do a lap of the waypoints, but this time between each waypoint the device will
diff --git a/apps/CtsVerifier/res/xml/accessory_filter.xml b/apps/CtsVerifier/res/xml/accessory_filter.xml
index 21caaa4..4a1d779 100644
--- a/apps/CtsVerifier/res/xml/accessory_filter.xml
+++ b/apps/CtsVerifier/res/xml/accessory_filter.xml
@@ -14,5 +14,5 @@
limitations under the License.
-->
<resources>
- <usb-accessory manufacturer="Android CTS" model="CTS USB Accessory" version="1.0" />
+ <usb-accessory />
</resources>
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
index cf8ec89..a9445ac 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CommandReceiverActivity.java
@@ -29,6 +29,7 @@
import com.android.cts.verifier.R;
import com.android.cts.verifier.managedprovisioning.Utils;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
@@ -60,6 +61,9 @@
public static final String COMMAND_REMOVE_DEVICE_OWNER = "remove-device-owner";
public static final String COMMAND_REQUEST_BUGREPORT = "request-bugreport";
public static final String COMMAND_SET_USER_ICON = "set-user-icon";
+ public static final String COMMAND_RETRIEVE_NETWORK_LOGS = "retrieve-network-logs";
+ public static final String COMMAND_RETRIEVE_SECURITY_LOGS = "retrieve-security-logs";
+ public static final String COMMAND_SET_ORGANIZATION_NAME = "set-organization-name";
public static final String EXTRA_USER_RESTRICTION =
"com.android.cts.verifier.managedprovisioning.extra.USER_RESTRICTION";
@@ -71,6 +75,9 @@
"com.android.cts.verifier.managedprovisioning.extra.ENFORCED";
public static final String EXTRA_VALUE =
"com.android.cts.verifier.managedprovisioning.extra.VALUE";
+ public static final String EXTRA_ORGANIZATION_NAME =
+ "com.android.cts.verifier.managedprovisioning.extra.ORGANIZATION_NAME";
+
private ComponentName mAdmin;
private DevicePolicyManager mDpm;
@@ -180,6 +187,35 @@
mDpm.setUserIcon(mAdmin, BitmapFactory.decodeResource(getResources(),
com.android.cts.verifier.R.drawable.icon));
} break;
+ case COMMAND_RETRIEVE_NETWORK_LOGS: {
+ if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+ return;
+ }
+ // STOPSHIP(b/33068581): Network logging will be un-hidden for O. Remove
+ // reflection when the un-hiding happens.
+ final Method setNetworkLoggingEnabledMethod =
+ DevicePolicyManager.class.getDeclaredMethod(
+ "setNetworkLoggingEnabled", ComponentName.class, boolean.class);
+ final Method retrieveNetworkLogsMethod =
+ DevicePolicyManager.class.getDeclaredMethod(
+ "retrieveNetworkLogs", ComponentName.class, long.class);
+ setNetworkLoggingEnabledMethod.invoke(mDpm, mAdmin, true);
+ retrieveNetworkLogsMethod.invoke(mDpm, mAdmin, 0 /* batchToken */);
+ setNetworkLoggingEnabledMethod.invoke(mDpm, mAdmin, false);
+ } break;
+ case COMMAND_RETRIEVE_SECURITY_LOGS: {
+ if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+ return;
+ }
+ mDpm.retrieveSecurityLogs(mAdmin);
+ } break;
+ case COMMAND_SET_ORGANIZATION_NAME: {
+ if (!mDpm.isDeviceOwnerApp(getPackageName())) {
+ return;
+ }
+ mDpm.setOrganizationName(mAdmin,
+ intent.getStringExtra(EXTRA_ORGANIZATION_NAME));
+ } break;
}
} catch (Exception e) {
Log.e(TAG, "Failed to execute command: " + intent, e);
@@ -188,7 +224,7 @@
}
}
- private void clearAllPolicies() {
+ private void clearAllPolicies() throws Exception {
clearProfileOwnerRelatedPolicies();
mDpm.clearUserRestriction(mAdmin, UserManager.DISALLOW_ADD_USER);
@@ -212,6 +248,12 @@
mDpm.setKeyguardDisabled(mAdmin, false);
mDpm.setAutoTimeRequired(mAdmin, false);
mDpm.setStatusBarDisabled(mAdmin, false);
+ // STOPSHIP(b/33068581): Network logging will be un-hidden for O. Remove reflection when the
+ // un-hiding happens.
+ final Method setNetworkLoggingEnabledMethod = DevicePolicyManager.class.getDeclaredMethod(
+ "setNetworkLoggingEnabled", ComponentName.class, boolean.class);
+ setNetworkLoggingEnabledMethod.invoke(mDpm, mAdmin, false);
+ mDpm.setOrganizationName(mAdmin, null);
}
private void clearProfileOwnerRelatedPolicies() {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
index 5b43f6a..cee7307 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
@@ -22,6 +22,7 @@
import android.content.Intent;
import android.database.DataSetObserver;
import android.os.Bundle;
+import android.provider.Settings;
import com.android.cts.verifier.ArrayTestListAdapter;
import com.android.cts.verifier.IntentDrivenTestActivity;
@@ -31,43 +32,30 @@
import com.android.cts.verifier.R;
import com.android.cts.verifier.TestListAdapter.TestListItem;
+import static com.android.cts.verifier.managedprovisioning.Utils.createInteractiveTestItem;
+
/**
* Activity that lists all device owner negative tests.
*/
public class DeviceOwnerNegativeTestActivity extends PassFailButtons.TestListActivity {
- private static final String DEVICE_OWNER_NEGATIVE_TEST = "DEVICE_OWNER_PROVISIONING_NEGATIVE";
+ private static final String DEVICE_OWNER_PROVISIONING_NEGATIVE
+ = "DEVICE_OWNER_PROVISIONING_NEGATIVE";
+ private static final String ENTERPRISE_PRIVACY_QUICK_SETTINGS_NEGATIVE
+ = "ENTERPRISE_PRIVACY_QUICK_SETTINGS_NEGATIVE";
+ private static final String ENTERPRISE_PRIVACY_KEYGUARD_NEGATIVE
+ = "ENTERPRISE_PRIVACY_KEYGUARD_NEGATIVE";
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pass_fail_list);
- setInfoResources(R.string.device_owner_provisioning_tests,
- R.string.device_owner_provisioning_tests_info, 0);
setPassFailButtonClickListeners();
- TestInfo deviceOwnerNegativeTestInfo = new TestInfo(
- DEVICE_OWNER_NEGATIVE_TEST,
- R.string.device_owner_negative_test,
- R.string.device_owner_negative_test_info,
- new ButtonInfo(
- R.string.start_device_owner_provisioning_button,
- new Intent(this, TrampolineActivity.class)));
-
final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
- adapter.add(TestListItem.newCategory(this, R.string.device_owner_provisioning_category));
+ adapter.add(TestListItem.newCategory(this, R.string.device_owner_negative_category));
- Intent startTestIntent = new Intent(this, IntentDrivenTestActivity.class)
- .putExtra(IntentDrivenTestActivity.EXTRA_ID,
- deviceOwnerNegativeTestInfo.getTestId())
- .putExtra(IntentDrivenTestActivity.EXTRA_TITLE,
- deviceOwnerNegativeTestInfo.getTitle())
- .putExtra(IntentDrivenTestActivity.EXTRA_INFO,
- deviceOwnerNegativeTestInfo.getInfoText())
- .putExtra(IntentDrivenTestActivity.EXTRA_BUTTONS,
- deviceOwnerNegativeTestInfo.getButtons());
-
- adapter.add(TestListItem.newTest(this, deviceOwnerNegativeTestInfo.getTitle(),
- deviceOwnerNegativeTestInfo.getTestId(), startTestIntent, null));
+ addTestsToAdapter(adapter);
adapter.registerDataSetObserver(new DataSetObserver() {
@Override
@@ -79,6 +67,41 @@
setTestListAdapter(adapter);
}
+ private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
+ final TestInfo provisioningNegativeTestInfo = new TestInfo(
+ DEVICE_OWNER_PROVISIONING_NEGATIVE,
+ R.string.device_owner_provisioning_negative,
+ R.string.device_owner_provisioning_negative_info,
+ new ButtonInfo(
+ R.string.start_device_owner_provisioning_button,
+ new Intent(this, TrampolineActivity.class)));
+ final Intent startTestIntent = new Intent(this, IntentDrivenTestActivity.class)
+ .putExtra(IntentDrivenTestActivity.EXTRA_ID,
+ provisioningNegativeTestInfo.getTestId())
+ .putExtra(IntentDrivenTestActivity.EXTRA_TITLE,
+ provisioningNegativeTestInfo.getTitle())
+ .putExtra(IntentDrivenTestActivity.EXTRA_INFO,
+ provisioningNegativeTestInfo.getInfoText())
+ .putExtra(IntentDrivenTestActivity.EXTRA_BUTTONS,
+ provisioningNegativeTestInfo.getButtons());
+ adapter.add(TestListItem.newTest(this, provisioningNegativeTestInfo.getTitle(),
+ provisioningNegativeTestInfo.getTestId(), startTestIntent, null));
+ adapter.add(TestListItem.newTest(this, R.string.enterprise_privacy_quick_settings_negative,
+ ENTERPRISE_PRIVACY_QUICK_SETTINGS_NEGATIVE,
+ new Intent(this, EnterprisePrivacyInfoOnlyTestActivity.class)
+ .putExtra(EnterprisePrivacyInfoOnlyTestActivity.EXTRA_ID,
+ ENTERPRISE_PRIVACY_QUICK_SETTINGS_NEGATIVE)
+ .putExtra(EnterprisePrivacyInfoOnlyTestActivity.EXTRA_TITLE,
+ R.string.enterprise_privacy_quick_settings_negative)
+ .putExtra(EnterprisePrivacyInfoOnlyTestActivity.EXTRA_INFO,
+ R.string.enterprise_privacy_quick_settings_negative_info),
+ null));
+ adapter.add(createInteractiveTestItem(this, ENTERPRISE_PRIVACY_KEYGUARD_NEGATIVE,
+ R.string.enterprise_privacy_keyguard_negative,
+ R.string.enterprise_privacy_keyguard_negative_info,
+ new ButtonInfo(R.string.go_button_text, new Intent(Settings.ACTION_SETTINGS))));
+ }
+
/**
* This is needed because IntentDrivenTestActivity fires the intent by startActivity when
* a button is clicked, but ACTION_PROVISION_MANAGED_DEVICE requires to be fired by
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
index 024854c..b5ed29d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -70,6 +70,7 @@
private static final String DISALLOW_DATA_ROAMING_ID = "DISALLOW_DATA_ROAMING";
private static final String DISALLOW_FACTORY_RESET_ID = "DISALLOW_FACTORY_RESET";
private static final String POLICY_TRANSPARENCY_TEST_ID = "POLICY_TRANSPARENCY";
+ private static final String ENTERPRISE_PRIVACY_TEST_ID = "ENTERPRISE_PRIVACY";
private static final String REMOVE_DEVICE_OWNER_TEST_ID = "REMOVE_DEVICE_OWNER";
@Override
@@ -297,6 +298,15 @@
R.string.device_profile_owner_policy_transparency_test,
policyTransparencyTestIntent));
+ // Enterprise Privacy
+ final Intent enterprisePolicyTestIntent = new Intent(this,
+ EnterprisePrivacyTestListActivity.class);
+ enterprisePolicyTestIntent.putExtra(
+ EnterprisePrivacyTestListActivity.EXTRA_TEST_ID, ENTERPRISE_PRIVACY_TEST_ID);
+ adapter.add(createTestItem(this, ENTERPRISE_PRIVACY_TEST_ID,
+ R.string.enterprise_privacy_test,
+ enterprisePolicyTestIntent));
+
// removeDeviceOwner
adapter.add(createInteractiveTestItem(this, REMOVE_DEVICE_OWNER_TEST_ID,
R.string.device_owner_remove_device_owner_test,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyInfoOnlyTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyInfoOnlyTestActivity.java
new file mode 100644
index 0000000..99961dc
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyInfoOnlyTestActivity.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.verifier.managedprovisioning;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.widget.TextView;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+/**
+ * A test Activity that has an info text and pass/fail buttons, nothing else.
+ */
+public class EnterprisePrivacyInfoOnlyTestActivity extends PassFailButtons.Activity {
+ public static final String EXTRA_ID = "id";
+ public static final String EXTRA_TITLE = "title";
+ public static final String EXTRA_INFO = "info";
+
+ private String mTestId;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.enterprise_privacy_negative_test);
+ setPassFailButtonClickListeners();
+
+ final Intent intent = getIntent();
+ if (!intent.hasExtra(EXTRA_ID)
+ || !intent.hasExtra(EXTRA_TITLE)
+ || !intent.hasExtra(EXTRA_INFO)) {
+ throw new IllegalArgumentException(
+ "Intent must have EXTRA_ID, EXTRA_TITLE & EXTRA_INFO");
+ }
+
+ mTestId = intent.getStringExtra(EXTRA_ID);
+ setTitle(intent.getIntExtra(EXTRA_TITLE, -1));
+
+ final TextView info = (TextView) findViewById(R.id.info);
+ info.setText(intent.getIntExtra(EXTRA_INFO, -1));
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ setResult(RESULT_CANCELED);
+ }
+
+ @Override
+ public String getTestId() {
+ return mTestId;
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java
new file mode 100644
index 0000000..81a3404
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/EnterprisePrivacyTestListActivity.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.verifier.managedprovisioning;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.os.Bundle;
+import android.provider.Settings;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+
+import static com.android.cts.verifier.managedprovisioning.Utils.createInteractiveTestItem;
+
+/**
+ * Test class to verify privacy information is shown for devices managed by a Device Owner.
+ */
+public class EnterprisePrivacyTestListActivity extends PassFailButtons.TestListActivity {
+
+ private static final String ENTERPRISE_PRIVACY_PAGE = "ENTERPRISE_PRIVACY_PAGE";
+ private static final String ENTERPRISE_PRIVACY_NETWORK_LOGGING
+ = "ENTERPRISE_PRIVACY_NETWORK_LOGGING";
+ private static final String ENTERPRISE_PRIVACY_BUG_REPORT = "ENTERPRISE_PRIVACY_BUG_REPORT";
+ private static final String ENTERPRISE_PRIVACY_SECURITY_LOGGING
+ = "ENTERPRISE_PRIVACY_SECURITY_LOGGING";
+ private static final String ENTERPRISE_PRIVACY_QUICK_SETTINGS
+ = "ENTERPRISE_PRIVACY_QUICK_SETTINGS";
+ private static final String ENTERPRISE_PRIVACY_KEYGUARD = "ENTERPRISE_PRIVACY_KEYGUARD";
+
+ public static final String EXTRA_TEST_ID =
+ "com.android.cts.verifier.managedprovisioning.extra.TEST_ID";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.pass_fail_list);
+ setPassFailButtonClickListeners();
+ final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+ addTestsToAdapter(adapter);
+ adapter.registerDataSetObserver(new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ updatePassButton();
+ }
+ });
+ setTestListAdapter(adapter);
+ }
+
+ private Intent buildCommandIntent(String command) {
+ return new Intent(CommandReceiverActivity.ACTION_EXECUTE_COMMAND)
+ .putExtra(CommandReceiverActivity.EXTRA_COMMAND, command);
+ }
+
+ private TestListItem buildCommandTest(String id, int titleRes, int infoRes,
+ int commandButtonRes, String command) {
+ return createInteractiveTestItem(this, id, titleRes, infoRes,
+ new ButtonInfo[] {
+ new ButtonInfo(commandButtonRes, buildCommandIntent(command)),
+ new ButtonInfo(R.string.enterprise_privacy_open_settings,
+ new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS))});
+ }
+
+ private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
+ adapter.add(createInteractiveTestItem(this, ENTERPRISE_PRIVACY_PAGE,
+ R.string.enterprise_privacy_page,
+ R.string.enterprise_privacy_page_info,
+ new ButtonInfo(R.string.go_button_text, new Intent(Settings.ACTION_SETTINGS))));
+ adapter.add(buildCommandTest(ENTERPRISE_PRIVACY_NETWORK_LOGGING,
+ R.string.enterprise_privacy_network_logging,
+ R.string.enterprise_privacy_network_logging_info,
+ R.string.enterprise_privacy_retrieve_network_logs,
+ CommandReceiverActivity.COMMAND_RETRIEVE_NETWORK_LOGS));
+ adapter.add(buildCommandTest(ENTERPRISE_PRIVACY_BUG_REPORT,
+ R.string.enterprise_privacy_bug_report,
+ R.string.enterprise_privacy_bug_report_info,
+ R.string.enterprise_privacy_request_bug_report,
+ CommandReceiverActivity.COMMAND_REQUEST_BUGREPORT));
+ adapter.add(buildCommandTest(ENTERPRISE_PRIVACY_SECURITY_LOGGING,
+ R.string.enterprise_privacy_security_logging,
+ R.string.enterprise_privacy_security_logging_info,
+ R.string.enterprise_privacy_retrieve_security_logs,
+ CommandReceiverActivity.COMMAND_RETRIEVE_SECURITY_LOGS));
+ adapter.add(createInteractiveTestItem(this, ENTERPRISE_PRIVACY_QUICK_SETTINGS,
+ R.string.enterprise_privacy_quick_settings,
+ R.string.enterprise_privacy_quick_settings_info,
+ new ButtonInfo[] {
+ new ButtonInfo(R.string.enterprise_privacy_clear_organization,
+ buildCommandIntent(
+ CommandReceiverActivity.COMMAND_SET_ORGANIZATION_NAME)),
+ new ButtonInfo(R.string.enterprise_privacy_set_organization,
+ buildCommandIntent(
+ CommandReceiverActivity.COMMAND_SET_ORGANIZATION_NAME)
+ .putExtra(CommandReceiverActivity.EXTRA_ORGANIZATION_NAME,
+ "Foo, Inc."))}));
+ adapter.add(createInteractiveTestItem(this, ENTERPRISE_PRIVACY_KEYGUARD,
+ R.string.enterprise_privacy_keyguard,
+ R.string.enterprise_privacy_keyguard_info,
+ new ButtonInfo[] {
+ new ButtonInfo(R.string.enterprise_privacy_open_settings,
+ new Intent(Settings.ACTION_SETTINGS)),
+ new ButtonInfo(R.string.enterprise_privacy_clear_organization,
+ buildCommandIntent(
+ CommandReceiverActivity.COMMAND_SET_ORGANIZATION_NAME)),
+ new ButtonInfo(R.string.enterprise_privacy_set_organization,
+ buildCommandIntent(
+ CommandReceiverActivity.COMMAND_SET_ORGANIZATION_NAME)
+ .putExtra(CommandReceiverActivity.EXTRA_ORGANIZATION_NAME,
+ "Foo, Inc."))}));
+ }
+
+ @Override
+ public String getTestId() {
+ return getIntent().getStringExtra(EXTRA_TEST_ID);
+ }
+
+ @Override
+ public void finish() {
+ super.finish();
+ startActivity(buildCommandIntent(
+ CommandReceiverActivity.COMMAND_DEVICE_OWNER_CLEAR_POLICIES));
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/usb/Util.java b/apps/CtsVerifier/src/com/android/cts/verifier/usb/Util.java
new file mode 100644
index 0000000..5be1792
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/usb/Util.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.verifier.usb;
+
+import android.support.annotation.NonNull;
+import android.util.Log;
+
+/**
+ * Utilities for the USB CTS verifier tests.
+ */
+public class Util {
+ private static final String LOG_TAG = Util.class.getSimpleName();
+
+ /**
+ * Run a {@link Invokable} and expect a {@link Throwable}.
+ *
+ * @param r The {@link Invokable} to run
+ * @param expectedClass The expected {@link Throwable} type
+ */
+ public static void runAndAssertException(@NonNull Invokable r,
+ @NonNull Class<? extends Throwable> expectedClass) throws Throwable {
+ try {
+ r.run();
+ } catch (Throwable e) {
+ if (e.getClass().isAssignableFrom(expectedClass)) {
+ return;
+ } else {
+ Log.e(LOG_TAG, "Expected: " + expectedClass.getName() + ", got: "
+ + e.getClass().getName());
+ throw e;
+ }
+ }
+
+ throw new AssertionError("No throwable thrown");
+ }
+
+
+ /**
+ * A {@link Runnable} that can throw an {@link Throwable}.
+ */
+ public interface Invokable {
+ /**
+ * Run the code that might cause an exception.
+ */
+ void run() throws Throwable;
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/AccessoryAttachmentHandler.java b/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/AccessoryAttachmentHandler.java
new file mode 100644
index 0000000..f5e0fef
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/AccessoryAttachmentHandler.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.verifier.usb.accessory;
+
+import android.app.Activity;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbManager;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import java.util.ArrayList;
+
+/**
+ * Utility to receive callbacks when an USB accessory is attached.
+ */
+public class AccessoryAttachmentHandler extends Activity {
+ private static final ArrayList<AccessoryAttachmentObserver> sObservers = new ArrayList<>();
+
+ /**
+ * Register an observer to be called when an USB accessory connects.
+ *
+ * @param observer The observer that should be called when an USB accessory connects.
+ */
+ static void addObserver(@NonNull AccessoryAttachmentObserver observer) {
+ synchronized (sObservers) {
+ sObservers.add(observer);
+ }
+ }
+
+ /**
+ * Remove an observer that was added in {@link #addObserver}.
+ *
+ * @param observer The observer to remove
+ */
+ static void removeObserver(@NonNull AccessoryAttachmentObserver observer) {
+ synchronized (sObservers) {
+ sObservers.remove(observer);
+ }
+ }
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ UsbAccessory accessory = getIntent().getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
+
+ synchronized (sObservers) {
+ ArrayList<AccessoryAttachmentObserver> observers =
+ (ArrayList<AccessoryAttachmentObserver>) sObservers.clone();
+
+ for (AccessoryAttachmentObserver observer : observers) {
+ observer.onAttached(accessory);
+ }
+ }
+
+ finish();
+ }
+
+ /**
+ * Callback when an accessory is attached
+ */
+ interface AccessoryAttachmentObserver {
+ void onAttached(UsbAccessory accessory);
+ }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/UsbAccessoryTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/UsbAccessoryTestActivity.java
index 2e11f98..8ac009b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/UsbAccessoryTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/usb/accessory/UsbAccessoryTestActivity.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,460 +16,231 @@
package com.android.cts.verifier.usb.accessory;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-import com.android.cts.verifier.TestResult;
+import static com.android.cts.verifier.usb.Util.runAndAssertException;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.content.res.Configuration;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
import android.os.ParcelFileDescriptor;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.Toast;
+import android.widget.ProgressBar;
+import android.widget.TextView;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Random;
/**
- * Test for USB accessories. The test activity interacts with a cts-usb-accessory program that
- * acts as an accessory by exchanging a series of messages.
+ * Guide the user to run test for the USB accessory interface.
*/
-public class UsbAccessoryTestActivity extends PassFailButtons.Activity {
+public class UsbAccessoryTestActivity extends PassFailButtons.Activity implements
+ AccessoryAttachmentHandler.AccessoryAttachmentObserver {
+ private static final String LOG_TAG = UsbAccessoryTestActivity.class.getSimpleName();
+ private static final int MAX_BUFFER_SIZE = 16384;
- private static final String TAG = "UsbAccessoryTest";
-
- private static final int FILE_DESCRIPTOR_PROBLEM_DIALOG_ID = 1;
- private static final int STATE_START = 0;
- private static final int STATE_CONNECTED = 1;
- private static final int STATE_WAITING_FOR_RECONNECT = 2;
- private static final int STATE_RECONNECTED = 3;
- private static final int STATE_PASSED = 4;
-
- private static final String ACTION_USB_PERMISSION =
- "com.android.cts.verifier.usb.USB_PERMISSION";
-
- private ArrayAdapter<String> mReceivedMessagesAdapter;
- private ArrayAdapter<String> mSentMessagesAdapter;
- private MessageHandler mHandler;
- private Handler mMainHandler;
-
- private UsbManager mUsbManager;
- private PendingIntent mPermissionIntent;
- private boolean mPermissionRequestPending;
- private UsbReceiver mUsbReceiver;
- private int mState = STATE_START;
- private AlertDialog mDisconnectDialog;
- private AlertDialog mConnectDialog;
-
- private UsbAccessory mAccessory;
- private ParcelFileDescriptor mFileDescriptor;
-
- private Runnable mTimeoutRunnable = new Runnable() {
- @Override
- public void run() {
- Toast.makeText(UsbAccessoryTestActivity.this,
- R.string.usb_reconnect_timeout, Toast.LENGTH_SHORT).show();
- TestResult.setFailedResult(UsbAccessoryTestActivity.this, getTestId(), getTestDetails());
- }
- };
+ private TextView mStatus;
+ private ProgressBar mProgress;
@Override
- protected void onCreate(Bundle savedInstanceState) {
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Log.d(TAG, "onCreate");
- // Test success only works properly if launched from TestListActivity
- String action = getIntent().getAction();
- if (ACTION_USB_PERMISSION.equals(action)
- || UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(action)) {
- finish();
- return;
- }
setContentView(R.layout.usb_main);
- setInfoResources(R.string.usb_accessory_test, R.string.usb_accessory_test_info, -1);
- setPassFailButtonClickListeners();
+ setInfoResources(
+ R.string.usb_accessory_test, R.string.usb_accessory_test_info, -1);
- // Don't allow a test pass until the accessory and the Android device exchange messages...
+ mStatus = (TextView) findViewById(R.id.status);
+ mProgress = (ProgressBar) findViewById(R.id.progress_bar);
+ mStatus.setText(R.string.usb_accessory_test_step1);
getPassButton().setEnabled(false);
- if (!hasUsbAccessorySupport()) {
- showNoUsbAccessoryDialog();
- }
-
- mReceivedMessagesAdapter = new ArrayAdapter<String>(this, R.layout.usb_message_row);
- mSentMessagesAdapter = new ArrayAdapter<String>(this, R.layout.usb_message_row);
- mHandler = new MessageHandler();
-
- mUsbManager = (UsbManager) getSystemService(USB_SERVICE);
- mPermissionIntent = PendingIntent.getBroadcast(this, 0,
- new Intent(ACTION_USB_PERMISSION), 0);
-
- mUsbReceiver = new UsbReceiver();
- IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
- filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
- registerReceiver(mUsbReceiver, filter);
-
- setupListViews();
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setTitle(R.string.usb_reconnect_title)
- .setCancelable(false)
- .setNegativeButton(R.string.usb_reconnect_abort,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- setTestResultAndFinish(false);
- }
- });
- mConnectDialog = builder
- .setMessage(R.string.usb_connect_message)
- .create();
- mDisconnectDialog = builder
- .setMessage(R.string.usb_disconnect_message)
- .create();
-
- mMainHandler = new Handler(Looper.getMainLooper());
- }
-
- private boolean hasUsbAccessorySupport() {
- return getPackageManager().hasSystemFeature(PackageManager.FEATURE_USB_ACCESSORY);
- }
-
- private void showNoUsbAccessoryDialog() {
- new AlertDialog.Builder(this)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setTitle(R.string.usb_not_available_title)
- .setMessage(R.string.usb_not_available_message)
- .setCancelable(false)
- .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- finish();
- }
- })
- .show();
- }
-
- private void setupListViews() {
- ListView sentMessages = (ListView) findViewById(R.id.usb_sent_messages);
- ListView receivedMessages = (ListView) findViewById(R.id.usb_received_messages);
-
- View emptySentView = findViewById(R.id.usb_empty_sent_messages);
- View emptyReceivedView = findViewById(R.id.usb_empty_received_messages);
- sentMessages.setEmptyView(emptySentView);
- receivedMessages.setEmptyView(emptyReceivedView);
-
- receivedMessages.setAdapter(mReceivedMessagesAdapter);
- sentMessages.setAdapter(mSentMessagesAdapter);
- }
-
- class UsbReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Log.d(TAG, "Received broadcast: intent=" + intent);
- if (ACTION_USB_PERMISSION.equals(intent.getAction())) {
- if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
- UsbAccessory accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
- openAccessory(accessory);
- } else {
- Log.i(TAG, "Permission denied...");
- }
- mPermissionRequestPending = false;
- } else if (mState == STATE_WAITING_FOR_RECONNECT &&
- UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(intent.getAction())) {
- UsbAccessory accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
- if (accessory.equals(mAccessory)) {
- closeAccessory();
- mDisconnectDialog.dismiss();
- mConnectDialog.show();
- mMainHandler.postDelayed(mTimeoutRunnable, 10000 /* 10 seconds */);
- }
- }
- }
- }
-
- public void onNewIntent(Intent intent) {
- super.onNewIntent(intent);
- Log.d(TAG, "onNewIntent: state=" + mState + ", intent=" + intent);
- if (UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(intent.getAction())) {
- UsbAccessory accessory = intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
- openAccessory(accessory);
- }
- }
-
- private void openAccessory(UsbAccessory accessory) {
- mAccessory = accessory;
- mFileDescriptor = mUsbManager.openAccessory(accessory);
- if (mState == STATE_START) {
- setState(STATE_CONNECTED);
- } else if (mState == STATE_WAITING_FOR_RECONNECT) {
- setState(STATE_RECONNECTED);
- mConnectDialog.dismiss();
- }
- if (mFileDescriptor != null) {
- FileDescriptor fileDescriptor = mFileDescriptor.getFileDescriptor();
- FileInputStream inputStream = new FileInputStream(fileDescriptor);
- FileOutputStream outputStream = new FileOutputStream(fileDescriptor);
- new MessageThread(inputStream, outputStream, mHandler).start();
- } else {
- showDialog(FILE_DESCRIPTOR_PROBLEM_DIALOG_ID);
- }
- }
-
- private void closeAccessory() {
- mAccessory = null;
- if (mFileDescriptor != null) {
- try {
- mFileDescriptor.close();
- } catch (IOException e) {
- Log.e(TAG, "Exception while closing file descriptor", e);
- } finally {
- mFileDescriptor = null;
- }
- }
- }
-
- static class MessageThread extends Thread {
-
- private final InputStream mInputStream;
-
- private final OutputStream mOutputStream;
-
- private final MessageHandler mHandler;
-
- private int mNextMessageNumber = 0;
-
- MessageThread(InputStream inputStream, OutputStream outputStream, MessageHandler handler) {
- this.mInputStream = inputStream;
- this.mOutputStream = outputStream;
- this.mHandler = handler;
- }
-
- @Override
- public void run() {
- mHandler.sendEmptyMessage(MessageHandler.MESSAGE_THREAD_STARTING);
-
- try {
- // Wait a bit or else the messages can appear to quick and be confusing...
- Thread.sleep(2000);
- sendMessage();
-
- // Wait for response and send message acks...
- int numRead = 0;
- byte[] buffer = new byte[16384];
- boolean done = false;
- while (numRead >= 0 && !done) {
- numRead = mInputStream.read(buffer);
- if (numRead > 0) {
- done = handleReceivedMessage(buffer, numRead);
- }
- }
- } catch (IOException e) {
- Log.e(TAG, "Exception while reading from input stream", e);
- mHandler.sendEmptyMessage(MessageHandler.MESSAGE_THREAD_EXCEPTION);
- } catch (InterruptedException e) {
- Log.e(TAG, "Exception while reading from input stream", e);
- mHandler.sendEmptyMessage(MessageHandler.MESSAGE_THREAD_EXCEPTION);
- }
- mHandler.sendEmptyMessage(MessageHandler.MESSAGE_THREAD_ENDING);
- }
-
- private boolean handleReceivedMessage(byte[] buffer, int numRead) throws IOException {
- // TODO: Check the contents of the message?
- String text = new String(buffer, 0, numRead).trim();
- mHandler.sendReceivedMessage(text);
-
- // Send back a response..
- if (mNextMessageNumber <= 10) {
- sendMessage();
- return false;
- } else {
- mHandler.sendEmptyMessage(MessageHandler.STAGE_PASSED);
- return true;
- }
- }
-
- private void sendMessage() throws IOException {
- String text = "Message from Android device #" + mNextMessageNumber++;
- mOutputStream.write(text.getBytes());
- mHandler.sendSentMessage(text);
- }
- }
-
- class MessageHandler extends Handler {
-
- static final int RECEIVED_MESSAGE = 1;
-
- static final int SENT_MESSAGE = 2;
-
- static final int MESSAGE_THREAD_STARTING = 3;
-
- static final int MESSAGE_THREAD_EXCEPTION = 4;
-
- static final int MESSAGE_THREAD_ENDING = 5;
-
- static final int STAGE_PASSED = 6;
-
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- switch (msg.what) {
- case RECEIVED_MESSAGE:
- mReceivedMessagesAdapter.add((String) msg.obj);
- break;
-
- case SENT_MESSAGE:
- mSentMessagesAdapter.add((String) msg.obj);
- break;
-
- case MESSAGE_THREAD_STARTING:
- showToast(R.string.usb_message_thread_started);
- break;
-
- case MESSAGE_THREAD_EXCEPTION:
- showToast(R.string.usb_message_thread_exception);
- break;
-
- case MESSAGE_THREAD_ENDING:
- showToast(R.string.usb_message_thread_ended);
- break;
-
- case STAGE_PASSED:
- if (mState == STATE_RECONNECTED) {
- showToast(R.string.usb_test_passed);
- getPassButton().setEnabled(true);
- setState(STATE_PASSED);
- mMainHandler.removeCallbacks(mTimeoutRunnable);
- } else if (mState == STATE_CONNECTED) {
- mDisconnectDialog.show();
- setState(STATE_WAITING_FOR_RECONNECT);
- }
- break;
-
- default:
- throw new IllegalArgumentException("Bad message type: " + msg.what);
- }
- }
-
- private void showToast(int messageId) {
- Toast.makeText(UsbAccessoryTestActivity.this, messageId, Toast.LENGTH_SHORT).show();
- }
-
- void sendReceivedMessage(String text) {
- Message message = Message.obtain(this, RECEIVED_MESSAGE);
- message.obj = text;
- sendMessage(message);
- }
-
- void sendSentMessage(String text) {
- Message message = Message.obtain(this, SENT_MESSAGE);
- message.obj = text;
- sendMessage(message);
- }
+ AccessoryAttachmentHandler.addObserver(this);
}
@Override
- protected void onResume() {
- super.onResume();
- Log.d(TAG, "onResume: state=" + stateToString(mState));
- if (mState == STATE_START) {
- UsbAccessory[] accessories = mUsbManager.getAccessoryList();
- UsbAccessory accessory = accessories != null && accessories.length > 0
- ? accessories[0]
- : null;
- if (accessory != null) {
- if (mUsbManager.hasPermission(accessory)) {
- openAccessory(accessory);
- } else {
- if (!mPermissionRequestPending) {
- mUsbManager.requestPermission(accessory, mPermissionIntent);
- mPermissionRequestPending = true;
- }
+ public void onAttached(UsbAccessory accessory) {
+ mStatus.setText(R.string.usb_accessory_test_step2);
+ mProgress.setVisibility(View.VISIBLE);
+
+ AccessoryAttachmentHandler.removeObserver(this);
+
+ UsbManager usbManager = getSystemService(UsbManager.class);
+
+ try {
+ assertEquals("Android device running CTS verifier", accessory.getDescription());
+ assertEquals("Android", accessory.getManufacturer());
+ assertEquals("Android device", accessory.getModel());
+ assertEquals("0", accessory.getSerial());
+ assertEquals("https://source.android.com/compatibility/cts/verifier.html",
+ accessory.getUri());
+ assertEquals("1", accessory.getVersion());
+
+ assertTrue(Arrays.asList(usbManager.getAccessoryList()).contains(accessory));
+
+ runAndAssertException(() -> usbManager.openAccessory(null), NullPointerException.class);
+
+ ParcelFileDescriptor accessoryFd = usbManager.openAccessory(accessory);
+ assertNotNull(accessoryFd);
+
+ try (InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(accessoryFd)) {
+ try (OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(
+ accessoryFd)) {
+ byte[] origBuffer32 = new byte[32];
+ (new Random()).nextBytes(origBuffer32);
+
+ byte[] origBufferMax = new byte[MAX_BUFFER_SIZE];
+ (new Random()).nextBytes(origBufferMax);
+
+ byte[] bufferMax = new byte[MAX_BUFFER_SIZE];
+ byte[] buffer32 = new byte[32];
+ byte[] buffer16 = new byte[16];
+
+ // Echo a transfer
+ nextTest(is, os, "echo 32 bytes");
+
+ os.write(origBuffer32);
+
+ int numRead = is.read(buffer32);
+ assertEquals(32, numRead);
+ assertArrayEquals(origBuffer32, buffer32);
+
+ // Receive less data than available
+ nextTest(is, os, "echo 32 bytes");
+
+ os.write(origBuffer32);
+
+ numRead = is.read(buffer16);
+ assertEquals(16, numRead);
+ assertArrayEquals(Arrays.copyOf(origBuffer32, 16), buffer16);
+
+ // If a transfer was only partially read, the rest of the transfer is lost.
+ // We cannot read the second part, hence proceed to the next test.
+
+ // Send two transfers in a row
+ nextTest(is, os, "echo two 16 byte transfers as one");
+
+ os.write(Arrays.copyOf(origBuffer32, 16));
+ os.write(Arrays.copyOfRange(origBuffer32, 16, 32));
+
+ numRead = is.read(buffer32);
+ assertEquals(32, numRead);
+ assertArrayEquals(origBuffer32, buffer32);
+
+ // Receive two transfers in a row into a buffer that is bigger than the transfer
+ nextTest(is, os, "echo 32 bytes as two 16 byte transfers");
+
+ os.write(origBuffer32);
+
+ // Even though the buffer would hold 32 bytes the input stream will read the
+ // transfers individually
+ numRead = is.read(buffer32);
+ assertEquals(16, numRead);
+ assertArrayEquals(Arrays.copyOf(origBuffer32, 16),
+ Arrays.copyOf(buffer32, 16));
+
+ numRead = is.read(buffer32);
+ assertEquals(16, numRead);
+ assertArrayEquals(Arrays.copyOfRange(origBuffer32, 16, 32),
+ Arrays.copyOf(buffer32, 16));
+
+ // Echo a buffer with the maximum size
+ nextTest(is, os, "echo max bytes");
+
+ os.write(origBufferMax);
+
+ numRead = is.read(bufferMax);
+ assertEquals(MAX_BUFFER_SIZE, numRead);
+ assertArrayEquals(origBufferMax, bufferMax);
+
+ // Echo a buffer with twice the maximum size
+ nextTest(is, os, "echo max*2 bytes");
+
+ byte[] oversizeBuffer = new byte[MAX_BUFFER_SIZE * 2];
+ System.arraycopy(origBufferMax, 0, oversizeBuffer, 0, MAX_BUFFER_SIZE);
+ System.arraycopy(origBufferMax, 0, oversizeBuffer, MAX_BUFFER_SIZE,
+ MAX_BUFFER_SIZE);
+ os.write(oversizeBuffer);
+
+ // The other side can not write more than the maximum size at once, hence we get
+ // two transfers in return
+ numRead = is.read(bufferMax);
+ assertEquals(MAX_BUFFER_SIZE, numRead);
+ assertArrayEquals(origBufferMax, bufferMax);
+
+ numRead = is.read(bufferMax);
+ assertEquals(MAX_BUFFER_SIZE, numRead);
+ assertArrayEquals(origBufferMax, bufferMax);
+
+ nextTest(is, os, "done");
}
}
+
+ accessoryFd.close();
+
+ setTestResultAndFinish(true);
+ } catch (Throwable t) {
+ fail(null, t);
}
}
- @Override
- protected void onPause() {
- super.onPause();
- Log.d(TAG, "onPause: state=" + stateToString(mState));
- }
+ /**
+ * Signal to the companion device that we want to switch to the next test.
+ *
+ * @param is The input stream from the companion device
+ * @param os The output stream from the companion device
+ * @param testName The name of the new test
+ */
+ private boolean nextTest(@NonNull InputStream is, @NonNull OutputStream os,
+ @NonNull String testName) throws IOException {
+ Log.i(LOG_TAG, "Init new test " + testName);
- @Override
- protected void onStop() {
- super.onStop();
- Log.d(TAG, "onStop: state=" + stateToString(mState));
- closeAccessory();
- }
+ ByteBuffer nameBuffer = Charset.forName("UTF-8").encode(CharBuffer.wrap(testName));
+ byte[] sizeBuffer = {(byte) nameBuffer.limit()};
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- setContentView(R.layout.usb_main);
- setupListViews();
- }
+ os.write(sizeBuffer);
+ os.write(Arrays.copyOf(nameBuffer.array(), nameBuffer.limit()));
- @Override
- public Dialog onCreateDialog(int id, Bundle args) {
- switch (id) {
- case FILE_DESCRIPTOR_PROBLEM_DIALOG_ID:
- return new AlertDialog.Builder(this)
- .setIcon(android.R.drawable.ic_dialog_alert)
- .setTitle(R.string.usb_accessory_test)
- .setMessage(R.string.usb_file_descriptor_error)
- .create();
-
- default:
- return super.onCreateDialog(id, args);
+ int ret = is.read();
+ if (ret <= 0) {
+ Log.i(LOG_TAG, "Last test failed " + ret);
+ return false;
}
+
+ os.write(0);
+
+ Log.i(LOG_TAG, "Running " + testName);
+
+ return true;
}
@Override
protected void onDestroy() {
+ AccessoryAttachmentHandler.removeObserver(this);
+
super.onDestroy();
- Log.d(TAG, "onDestroy");
- if (mUsbReceiver != null) {
- unregisterReceiver(mUsbReceiver);
- }
}
- private void setState(int newState) {
- Log.d(TAG, "Transition: " + stateToString(mState) + " -> " + stateToString(newState));
- mState = newState;
+ /**
+ * Indicate that the test failed.
+ */
+ private void fail(@Nullable String s, @Nullable Throwable e) {
+ Log.e(LOG_TAG, s, e);
+ setTestResultAndFinish(false);
}
-
-
- private static String stateToString(int state) {
- switch (state) {
- case STATE_START: return "START";
- case STATE_CONNECTED: return "CONNECTED";
- case STATE_WAITING_FOR_RECONNECT: return "WAITING_FOR_RECONNECT";
- case STATE_RECONNECTED: return "RECONNECTED";
- case STATE_PASSED: return "PASSED";
- default: return "UNKNOWN";
- }
- }
-
}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/usb/device/UsbDeviceTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/usb/device/UsbDeviceTestActivity.java
index d762096..6a1a16a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/usb/device/UsbDeviceTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/usb/device/UsbDeviceTestActivity.java
@@ -16,6 +16,8 @@
package com.android.cts.verifier.usb.device;
+import static com.android.cts.verifier.usb.Util.runAndAssertException;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -45,6 +47,9 @@
import android.util.ArraySet;
import android.util.Log;
import android.util.Pair;
+import android.view.View;
+import android.widget.ProgressBar;
+import android.widget.TextView;
import android.widget.Toast;
import com.android.cts.verifier.PassFailButtons;
@@ -72,37 +77,35 @@
private static final int MAX_BUFFER_SIZE = 16384;
private UsbManager mUsbManager;
- private final BroadcastReceiver mUsbDeviceConnectionReceiver;
+ private BroadcastReceiver mUsbDeviceConnectionReceiver;
private Thread mTestThread;
+ private TextView mStatus;
+ private ProgressBar mProgress;
private static long now() {
return System.nanoTime() / 1000000;
}
- /**
- * Run a {@link Invokable} and expect a {@link Throwable} of a certain type.
- *
- * @param r The {@link Invokable} to run
- * @param expectedClass The expected {@link Throwable} type
- */
- private static void assertException(@NonNull Invokable r,
- @NonNull Class<? extends Throwable> expectedClass) throws Throwable {
- try {
- r.run();
- } catch (Throwable e) {
- if (e.getClass().isAssignableFrom(expectedClass)) {
- return;
- } else {
- Log.e(LOG_TAG, "Expected: " + expectedClass.getName() + ", got: "
- + e.getClass().getName());
- throw e;
- }
- }
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
- throw new AssertionError("No throwable thrown");
- }
+ setContentView(R.layout.usb_main);
+ setInfoResources(R.string.usb_device_test, R.string.usb_device_test_info, -1);
- public UsbDeviceTestActivity() {
+ mStatus = (TextView) findViewById(R.id.status);
+ mProgress = (ProgressBar) findViewById(R.id.progress_bar);
+
+ mUsbManager = getSystemService(UsbManager.class);
+
+ getPassButton().setEnabled(false);
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_USB_PERMISSION);
+ filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+
+ mStatus.setText(R.string.usb_device_test_step1);
+
mUsbDeviceConnectionReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -111,6 +114,10 @@
switch (intent.getAction()) {
case UsbManager.ACTION_USB_DEVICE_ATTACHED:
+ if (!AoapInterface.isDeviceInAoapMode(device)) {
+ mStatus.setText(R.string.usb_device_test_step2);
+ }
+
mUsbManager.requestPermission(device,
PendingIntent.getBroadcast(UsbDeviceTestActivity.this, 0,
new Intent(ACTION_USB_PERMISSION), 0));
@@ -121,6 +128,8 @@
if (granted) {
if (!AoapInterface.isDeviceInAoapMode(device)) {
+ mStatus.setText(R.string.usb_device_test_step3);
+
UsbDeviceConnection connection = mUsbManager.openDevice(device);
try {
makeThisDeviceAnAccessory(connection);
@@ -128,6 +137,13 @@
connection.close();
}
} else {
+ mStatus.setText(R.string.usb_device_test_step4);
+ mProgress.setIndeterminate(true);
+ mProgress.setVisibility(View.VISIBLE);
+
+ unregisterReceiver(mUsbDeviceConnectionReceiver);
+ mUsbDeviceConnectionReceiver = null;
+
// Do not run test on main thread
mTestThread = new Thread() {
@Override
@@ -147,22 +163,6 @@
}
}
};
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.usb_main);
- setInfoResources(R.string.usb_device_test, R.string.usb_device_test_info, -1);
-
- mUsbManager = getSystemService(UsbManager.class);
-
- getPassButton().setEnabled(false);
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(ACTION_USB_PERMISSION);
- filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
registerReceiver(mUsbDeviceConnectionReceiver, filter);
}
@@ -390,22 +390,22 @@
* @throws Throwable
*/
private void ctrlTransferTests(@NonNull UsbDeviceConnection connection) throws Throwable {
- assertException(() -> connection.controlTransfer(0, 0, 0, 0, null, 1, 0),
+ runAndAssertException(() -> connection.controlTransfer(0, 0, 0, 0, null, 1, 0),
IllegalArgumentException.class);
- assertException(() -> connection.controlTransfer(0, 0, 0, 0, new byte[1], -1, 0),
+ runAndAssertException(() -> connection.controlTransfer(0, 0, 0, 0, new byte[1], -1, 0),
IllegalArgumentException.class);
- assertException(() -> connection.controlTransfer(0, 0, 0, 0, new byte[1], 2, 0),
+ runAndAssertException(() -> connection.controlTransfer(0, 0, 0, 0, new byte[1], 2, 0),
IllegalArgumentException.class);
- assertException(() -> connection.controlTransfer(0, 0, 0, 0, null, 0, 1, 0),
+ runAndAssertException(() -> connection.controlTransfer(0, 0, 0, 0, null, 0, 1, 0),
IllegalArgumentException.class);
- assertException(() -> connection.controlTransfer(0, 0, 0, 0, new byte[1], 0, -1, 0),
+ runAndAssertException(() -> connection.controlTransfer(0, 0, 0, 0, new byte[1], 0, -1, 0),
IllegalArgumentException.class);
- assertException(() -> connection.controlTransfer(0, 0, 0, 0, new byte[1], 1, 1, 0),
+ runAndAssertException(() -> connection.controlTransfer(0, 0, 0, 0, new byte[1], 1, 1, 0),
IllegalArgumentException.class);
}
@@ -729,7 +729,7 @@
*/
private void timeoutWhileWaitingForUsbRequest(@NonNull UsbDeviceConnection connection)
throws Throwable {
- assertException(() -> connection.requestWait(-1), IllegalArgumentException.class);
+ runAndAssertException(() -> connection.requestWait(-1), IllegalArgumentException.class);
long startTime = now();
UsbRequest req = connection.requestWait(100);
@@ -981,18 +981,19 @@
// Illegal arguments
final UsbRequest req1 = new UsbRequest();
- assertException(() -> req1.initialize(null, in), NullPointerException.class);
- assertException(() -> req1.initialize(connection, null), NullPointerException.class);
+ runAndAssertException(() -> req1.initialize(null, in), NullPointerException.class);
+ runAndAssertException(() -> req1.initialize(connection, null), NullPointerException.class);
boolean isInited = req1.initialize(connection, in);
assertTrue(isInited);
- assertException(() -> req1.queue(null, 0), NullPointerException.class);
- assertException(() -> req1.queue(ByteBuffer.allocate(1).asReadOnlyBuffer(), 1),
+ runAndAssertException(() -> req1.queue(null, 0), NullPointerException.class);
+ runAndAssertException(() -> req1.queue(ByteBuffer.allocate(1).asReadOnlyBuffer(), 1),
IllegalArgumentException.class);
req1.close();
// Cannot queue closed request
- assertException(() -> req1.queue(ByteBuffer.allocate(1), 1), NullPointerException.class);
- assertException(() -> req1.queue(ByteBuffer.allocateDirect(1), 1),
+ runAndAssertException(() -> req1.queue(ByteBuffer.allocate(1), 1),
+ NullPointerException.class);
+ runAndAssertException(() -> req1.queue(ByteBuffer.allocateDirect(1), 1),
NullPointerException.class);
}
@@ -1096,19 +1097,20 @@
// Illegal arguments
final UsbRequest req1 = new UsbRequest();
- assertException(() -> req1.initialize(null, in), NullPointerException.class);
- assertException(() -> req1.initialize(connection, null), NullPointerException.class);
+ runAndAssertException(() -> req1.initialize(null, in), NullPointerException.class);
+ runAndAssertException(() -> req1.initialize(connection, null), NullPointerException.class);
boolean isInited = req1.initialize(connection, in);
assertTrue(isInited);
- assertException(() -> req1.enqueue(ByteBuffer.allocate(16384 + 1).asReadOnlyBuffer()),
+ runAndAssertException(() -> req1.enqueue(ByteBuffer.allocate(16384 + 1).asReadOnlyBuffer()),
IllegalArgumentException.class);
- assertException(() -> req1.enqueue(ByteBuffer.allocate(1).asReadOnlyBuffer()),
+ runAndAssertException(() -> req1.enqueue(ByteBuffer.allocate(1).asReadOnlyBuffer()),
IllegalArgumentException.class);
req1.close();
// Cannot queue closed request
- assertException(() -> req1.enqueue(ByteBuffer.allocate(1)), IllegalStateException.class);
- assertException(() -> req1.enqueue(ByteBuffer.allocateDirect(1)),
+ runAndAssertException(() -> req1.enqueue(ByteBuffer.allocate(1)),
+ IllegalStateException.class);
+ runAndAssertException(() -> req1.enqueue(ByteBuffer.allocateDirect(1)),
IllegalStateException.class);
// Initialize
@@ -1629,27 +1631,27 @@
receiveOversizedBulkTransfer(connection, in);
// Illegal arguments
- assertException(() -> connection.bulkTransfer(out, new byte[1], 2, 0),
+ runAndAssertException(() -> connection.bulkTransfer(out, new byte[1], 2, 0),
IllegalArgumentException.class);
- assertException(() -> connection.bulkTransfer(in, new byte[1], 2, 0),
+ runAndAssertException(() -> connection.bulkTransfer(in, new byte[1], 2, 0),
IllegalArgumentException.class);
- assertException(() -> connection.bulkTransfer(out, new byte[2], 1, 2, 0),
+ runAndAssertException(() -> connection.bulkTransfer(out, new byte[2], 1, 2, 0),
IllegalArgumentException.class);
- assertException(() -> connection.bulkTransfer(in, new byte[2], 1, 2, 0),
+ runAndAssertException(() -> connection.bulkTransfer(in, new byte[2], 1, 2, 0),
IllegalArgumentException.class);
- assertException(() -> connection.bulkTransfer(out, new byte[1], -1, 0),
+ runAndAssertException(() -> connection.bulkTransfer(out, new byte[1], -1, 0),
IllegalArgumentException.class);
- assertException(() -> connection.bulkTransfer(in, new byte[1], -1, 0),
+ runAndAssertException(() -> connection.bulkTransfer(in, new byte[1], -1, 0),
IllegalArgumentException.class);
- assertException(() -> connection.bulkTransfer(out, new byte[1], 1, -1, 0),
+ runAndAssertException(() -> connection.bulkTransfer(out, new byte[1], 1, -1, 0),
IllegalArgumentException.class);
- assertException(() -> connection.bulkTransfer(in, new byte[1], 1, -1, 0),
+ runAndAssertException(() -> connection.bulkTransfer(in, new byte[1], 1, -1, 0),
IllegalArgumentException.class);
- assertException(() -> connection.bulkTransfer(out, new byte[1], -1, -1, 0),
+ runAndAssertException(() -> connection.bulkTransfer(out, new byte[1], -1, -1, 0),
IllegalArgumentException.class);
- assertException(() -> connection.bulkTransfer(in, new byte[1], -1, -1, 0),
+ runAndAssertException(() -> connection.bulkTransfer(in, new byte[1], -1, -1, 0),
IllegalArgumentException.class);
- assertException(() -> connection.bulkTransfer(null, new byte[1], 1, 0),
+ runAndAssertException(() -> connection.bulkTransfer(null, new byte[1], 1, 0),
NullPointerException.class);
// Transmissions that do nothing
@@ -1768,9 +1770,11 @@
released = connection.releaseInterface(iface);
assertTrue(released);
- assertException(() -> connection.claimInterface(null, true), NullPointerException.class);
- assertException(() -> connection.claimInterface(null, false), NullPointerException.class);
- assertException(() -> connection.releaseInterface(null), NullPointerException.class);
+ runAndAssertException(() -> connection.claimInterface(null, true),
+ NullPointerException.class);
+ runAndAssertException(() -> connection.claimInterface(null, false),
+ NullPointerException.class);
+ runAndAssertException(() -> connection.releaseInterface(null), NullPointerException.class);
}
/**
@@ -1803,7 +1807,7 @@
boolean released = connection.releaseInterface(iface);
assertTrue(released);
- assertException(() -> connection.setConfiguration(null), NullPointerException.class);
+ runAndAssertException(() -> connection.setConfiguration(null), NullPointerException.class);
}
/**
@@ -1832,7 +1836,7 @@
released = connection.releaseInterface(iface);
assertTrue(released);
- assertException(() -> connection.setInterface(null), NullPointerException.class);
+ runAndAssertException(() -> connection.setInterface(null), NullPointerException.class);
}
/**
@@ -2010,14 +2014,10 @@
@Override
protected void onDestroy() {
- unregisterReceiver(mUsbDeviceConnectionReceiver);
- super.onDestroy();
- }
+ if (mUsbDeviceConnectionReceiver != null) {
+ unregisterReceiver(mUsbDeviceConnectionReceiver);
+ }
- /**
- * A {@link Runnable} that can throw an {@link Throwable}.
- */
- private interface Invokable {
- void run() throws Throwable;
+ super.onDestroy();
}
}
diff --git a/apps/CtsVerifierUSBCompanion/res/layout/main.xml b/apps/CtsVerifierUSBCompanion/res/layout/main.xml
index e3d45b2..6eb2cec 100644
--- a/apps/CtsVerifierUSBCompanion/res/layout/main.xml
+++ b/apps/CtsVerifierUSBCompanion/res/layout/main.xml
@@ -47,6 +47,13 @@
android:text="@string/device_test_button" />
<Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/deviceTest"
+ android:id="@+id/accessoryTest"
+ android:text="@string/accessory_test_button" />
+
+ <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/status"
diff --git a/apps/CtsVerifierUSBCompanion/res/values/strings.xml b/apps/CtsVerifierUSBCompanion/res/values/strings.xml
index 99b2d24..56bc71f 100644
--- a/apps/CtsVerifierUSBCompanion/res/values/strings.xml
+++ b/apps/CtsVerifierUSBCompanion/res/values/strings.xml
@@ -18,6 +18,7 @@
<resources>
<string name="status_label">Status:</string>
<string name="device_test_button">Start device test companion</string>
+ <string name="accessory_test_button">Start accessory test companion</string>
<string name="abort_button">Abort</string>
<string name="app_name">Cts Verifier USB Companion</string>
<string name="status_no_test">No test run</string>
diff --git a/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/AccessoryTestCompanion.java b/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/AccessoryTestCompanion.java
new file mode 100644
index 0000000..dc5cc3d
--- /dev/null
+++ b/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/AccessoryTestCompanion.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.verifierusbcompanion;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbEndpoint;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
+import android.support.annotation.NonNull;
+
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+
+/**
+ * Companion code for com.android.cts.verifier.usb.device.UsbAccessoryTestActivity
+ */
+class AccessoryTestCompanion extends TestCompanion {
+ private static final int MAX_BUFFER_SIZE = 16384;
+
+ private static final String ACTION_USB_PERMISSION =
+ "com.android.cts.verifierusbcompanion.USB_PERMISSION";
+
+ private UsbManager mUsbManager;
+ private BroadcastReceiver mUsbDeviceConnectionReceiver;
+ private UsbDevice mDevice;
+
+ AccessoryTestCompanion(@NonNull Context context, @NonNull TestObserver observer) {
+ super(context, observer);
+ }
+
+ /**
+ * @throws Throwable
+ */
+ @Override
+ protected void runTest() throws Throwable {
+ updateStatus("Waiting for device under test to connect");
+
+ mUsbManager = getContext().getSystemService(UsbManager.class);
+
+ mUsbDeviceConnectionReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ synchronized (AccessoryTestCompanion.this) {
+ UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+
+ switch (intent.getAction()) {
+ case UsbManager.ACTION_USB_DEVICE_ATTACHED:
+ if (mUsbManager.hasPermission(device)) {
+ onDeviceAccessPermitted(device);
+ } else {
+ mUsbManager.requestPermission(device,
+ PendingIntent.getBroadcast(getContext(), 0,
+ new Intent(ACTION_USB_PERMISSION), 0));
+ }
+ break;
+ case ACTION_USB_PERMISSION:
+ boolean granted = intent.getBooleanExtra(
+ UsbManager.EXTRA_PERMISSION_GRANTED, false);
+
+ if (granted) {
+ onDeviceAccessPermitted(device);
+ } else {
+ fail("Permission to connect to " + device.getProductName()
+ + " not granted");
+ }
+ break;
+ }
+ }
+ }
+ };
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ACTION_USB_PERMISSION);
+ filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+
+ getContext().registerReceiver(mUsbDeviceConnectionReceiver, filter);
+
+ synchronized (this) {
+ while (mDevice == null) {
+ wait();
+ }
+ }
+
+ UsbInterface iface = null;
+ for (int i = 0; i < mDevice.getConfigurationCount(); i++) {
+ if (mDevice.getInterface(i).getName().equals("Android Accessory Interface")) {
+ iface = mDevice.getInterface(i);
+ break;
+ }
+ }
+
+ UsbEndpoint in = getEndpoint(iface, UsbConstants.USB_DIR_IN);
+ UsbEndpoint out = getEndpoint(iface, UsbConstants.USB_DIR_OUT);
+
+ UsbDeviceConnection connection = mUsbManager.openDevice(mDevice);
+
+ try {
+ String testName;
+ do {
+ testName = nextTest(connection, in, out, true);
+
+ updateStatus("Running test \"" + testName + "\"");
+
+ switch (testName) {
+ case "echo 32 bytes": {
+ byte[] buffer = new byte[32];
+
+ int numTransferred = connection.bulkTransfer(in, buffer, 32, 0);
+ assertEquals(32, numTransferred);
+
+ numTransferred = connection.bulkTransfer(out, buffer, 32, 0);
+ assertEquals(32, numTransferred);
+ }
+ break;
+
+ case "echo two 16 byte transfers as one": {
+ byte[] buffer = new byte[48];
+
+ // We receive the individual transfers even if we wait for more data
+ int numTransferred = connection.bulkTransfer(in, buffer, 32, 0);
+ assertEquals(16, numTransferred);
+ numTransferred = connection.bulkTransfer(in, buffer, 16, 32, 0);
+ assertEquals(16, numTransferred);
+
+ numTransferred = connection.bulkTransfer(out, buffer, 32, 0);
+ assertEquals(32, numTransferred);
+ }
+ break;
+
+ case "echo 32 bytes as two 16 byte transfers": {
+ byte[] buffer = new byte[32];
+
+ int numTransferred = connection.bulkTransfer(in, buffer, 32, 0);
+ assertEquals(32, numTransferred);
+
+ numTransferred = connection.bulkTransfer(out, buffer, 16, 0);
+ assertEquals(16, numTransferred);
+ numTransferred = connection.bulkTransfer(out, buffer, 16, 16, 0);
+ assertEquals(16, numTransferred);
+ }
+ break;
+
+ case "echo max bytes": {
+ byte[] buffer = new byte[MAX_BUFFER_SIZE];
+
+ int numTransferred = connection.bulkTransfer(in, buffer, MAX_BUFFER_SIZE,
+ 0);
+ assertEquals(MAX_BUFFER_SIZE, numTransferred);
+
+ numTransferred = connection.bulkTransfer(out, buffer, MAX_BUFFER_SIZE, 0);
+ assertEquals(MAX_BUFFER_SIZE, numTransferred);
+ }
+ break;
+
+ case "echo max*2 bytes": {
+ byte[] buffer = new byte[MAX_BUFFER_SIZE * 2];
+
+ int numTransferred = connection.bulkTransfer(in, buffer, MAX_BUFFER_SIZE,
+ 0);
+ assertEquals(MAX_BUFFER_SIZE, numTransferred);
+
+ // Oversized transfers get split into two
+ numTransferred = connection.bulkTransfer(in, buffer, MAX_BUFFER_SIZE,
+ MAX_BUFFER_SIZE, 0);
+ assertEquals(MAX_BUFFER_SIZE, numTransferred);
+
+ numTransferred = connection.bulkTransfer(out, buffer, MAX_BUFFER_SIZE, 0);
+ assertEquals(MAX_BUFFER_SIZE, numTransferred);
+
+ numTransferred = connection.bulkTransfer(out, buffer, MAX_BUFFER_SIZE,
+ MAX_BUFFER_SIZE, 0);
+ assertEquals(MAX_BUFFER_SIZE, numTransferred);
+ }
+ break;
+
+ default:
+ break;
+ }
+ } while (!testName.equals("done"));
+ } finally {
+ connection.close();
+ }
+ }
+
+ /**
+ * If access to a device was permitted either make the device an accessory if it already is,
+ * start the test.
+ *
+ * @param device The device access was permitted to
+ */
+ private void onDeviceAccessPermitted(@NonNull UsbDevice device) {
+ if (!AoapInterface.isDeviceInAoapMode(device)) {
+ UsbDeviceConnection connection = mUsbManager.openDevice(device);
+ try {
+ makeThisDeviceAnAccessory(connection);
+ } finally {
+ connection.close();
+ }
+ } else {
+ getContext().unregisterReceiver(mUsbDeviceConnectionReceiver);
+ mUsbDeviceConnectionReceiver = null;
+
+ synchronized (AccessoryTestCompanion.this) {
+ mDevice = device;
+
+ AccessoryTestCompanion.this.notifyAll();
+ }
+ }
+ }
+
+ @NonNull private String nextTest(@NonNull UsbDeviceConnection connection,
+ @NonNull UsbEndpoint in, @NonNull UsbEndpoint out, boolean isSuccess) {
+ byte[] sizeBuffer = new byte[1];
+
+ updateStatus("Waiting for next test");
+
+ int numTransferred = connection.bulkTransfer(in, sizeBuffer, 1, 0);
+ assertEquals(1, numTransferred);
+
+ int nameSize = sizeBuffer[0];
+
+ byte[] nameBuffer = new byte[nameSize];
+ numTransferred = connection.bulkTransfer(in, nameBuffer, nameSize, 0);
+ assertEquals(nameSize, numTransferred);
+
+ numTransferred = connection.bulkTransfer(out, new byte[]{(byte) (isSuccess ? 1 : 0)}, 1, 0);
+ assertEquals(1, numTransferred);
+
+ numTransferred = connection.bulkTransfer(in, new byte[1], 1, 0);
+ assertEquals(1, numTransferred);
+
+ String name = Charset.forName("UTF-8").decode(ByteBuffer.wrap(nameBuffer)).toString();
+
+ updateStatus("Next test is " + name);
+
+ return name;
+ }
+
+ /**
+ * Search an {@link UsbInterface} for an {@link UsbEndpoint endpoint} of a certain direction.
+ *
+ * @param iface The interface to search
+ * @param direction The direction the endpoint is for.
+ *
+ * @return The first endpoint found or {@link null}.
+ */
+ @NonNull private UsbEndpoint getEndpoint(@NonNull UsbInterface iface, int direction) {
+ for (int i = 0; i < iface.getEndpointCount(); i++) {
+ UsbEndpoint ep = iface.getEndpoint(i);
+ if (ep.getDirection() == direction) {
+ return ep;
+ }
+ }
+
+ throw new IllegalStateException("Could not find " + direction + " endpoint in "
+ + iface.getName());
+ }
+
+ /**
+ * Converts the device under test into an Android accessory. Accessories are USB hosts that are
+ * detected on the device side via {@link UsbManager#getAccessoryList()}.
+ *
+ * @param connection The connection to the USB device
+ */
+ private void makeThisDeviceAnAccessory(@NonNull UsbDeviceConnection connection) {
+ AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_MANUFACTURER,
+ "Android");
+ AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_MODEL,
+ "Android device");
+ AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_DESCRIPTION,
+ "Android device running CTS verifier");
+ AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_VERSION, "1");
+ AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_URI,
+ "https://source.android.com/compatibility/cts/verifier.html");
+ AoapInterface.sendString(connection, AoapInterface.ACCESSORY_STRING_SERIAL, "0");
+ AoapInterface.sendAoapStart(connection);
+ }
+}
diff --git a/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/AoapInterface.java b/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/AoapInterface.java
new file mode 100644
index 0000000..6f8d1a1
--- /dev/null
+++ b/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/AoapInterface.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.verifierusbcompanion;
+
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.util.Log;
+
+class AoapInterface {
+ /**
+ * Use Google Vendor ID when in accessory mode
+ */
+ private static final int USB_ACCESSORY_VENDOR_ID = 0x18D1;
+
+ /**
+ * Product ID to use when in accessory mode
+ */
+ private static final int USB_ACCESSORY_PRODUCT_ID = 0x2D00;
+
+ /**
+ * Product ID to use when in accessory mode and adb is enabled
+ */
+ private static final int USB_ACCESSORY_ADB_PRODUCT_ID = 0x2D01;
+
+ /**
+ * Indexes for strings sent by the host via ACCESSORY_SEND_STRING
+ */
+ public static final int ACCESSORY_STRING_MANUFACTURER = 0;
+ public static final int ACCESSORY_STRING_MODEL = 1;
+ public static final int ACCESSORY_STRING_DESCRIPTION = 2;
+ public static final int ACCESSORY_STRING_VERSION = 3;
+ public static final int ACCESSORY_STRING_URI = 4;
+ public static final int ACCESSORY_STRING_SERIAL = 5;
+
+ /**
+ * Control request for retrieving device's protocol version
+ *
+ * requestType: USB_DIR_IN | USB_TYPE_VENDOR
+ * request: ACCESSORY_GET_PROTOCOL
+ * value: 0
+ * index: 0
+ * data version number (16 bits little endian)
+ * 1 for original accessory support
+ * 2 adds HID and device to host audio support
+ */
+ private static final int ACCESSORY_GET_PROTOCOL = 51;
+
+ /**
+ * Control request for host to send a string to the device
+ *
+ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR
+ * request: ACCESSORY_SEND_STRING
+ * value: 0
+ * index: string ID
+ * data zero terminated UTF8 string
+ *
+ * The device can later retrieve these strings via the
+ * ACCESSORY_GET_STRING_* ioctls
+ */
+ private static final int ACCESSORY_SEND_STRING = 52;
+
+ /**
+ * Control request for starting device in accessory mode.
+ * The host sends this after setting all its strings to the device.
+ *
+ * requestType: USB_DIR_OUT | USB_TYPE_VENDOR
+ * request: ACCESSORY_START
+ * value: 0
+ * index: 0
+ * data none
+ */
+ private static final int ACCESSORY_START = 53;
+
+ private static final String TAG = AoapInterface.class.getSimpleName();
+
+ public static int getProtocol(UsbDeviceConnection conn) {
+ byte[] buffer = new byte[2];
+ int len = conn.controlTransfer(
+ UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_VENDOR,
+ AoapInterface.ACCESSORY_GET_PROTOCOL, 0, 0, buffer, 2, 10000);
+ if (len != 2) {
+ return -1;
+ }
+ return (buffer[1] << 8) | buffer[0];
+ }
+
+ public static void sendString(UsbDeviceConnection conn, int index, String string) {
+ byte[] buffer = (string + "\0").getBytes();
+ int len = conn.controlTransfer(
+ UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
+ AoapInterface.ACCESSORY_SEND_STRING, 0, index,
+ buffer, buffer.length, 10000);
+ if (len != buffer.length) {
+ throw new RuntimeException("Failed to send string " + index + ": \"" + string + "\"");
+ } else {
+ Log.i(TAG, "Sent string " + index + ": \"" + string + "\"");
+ }
+ }
+
+ public static void sendAoapStart(UsbDeviceConnection conn) {
+ int len = conn.controlTransfer(
+ UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_VENDOR,
+ AoapInterface.ACCESSORY_START, 0, 0, null, 0, 10000);
+ if (len < 0) {
+ throw new RuntimeException("control transfer for accessory start failed:" + len);
+ }
+ }
+
+ public static boolean isDeviceInAoapMode(UsbDevice device) {
+ final int vid = device.getVendorId();
+ final int pid = device.getProductId();
+ return vid == USB_ACCESSORY_VENDOR_ID
+ && (pid == USB_ACCESSORY_PRODUCT_ID
+ || pid == USB_ACCESSORY_ADB_PRODUCT_ID);
+ }
+}
diff --git a/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/Main.java b/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/Main.java
index 4b1bb39..a87f9ce 100644
--- a/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/Main.java
+++ b/apps/CtsVerifierUSBCompanion/src/com/android/cts/verifierusbcompanion/Main.java
@@ -16,10 +16,10 @@
package com.android.cts.verifierusbcompanion;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
import android.app.Activity;
import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
@@ -31,6 +31,7 @@
public class Main extends Activity implements TestCompanion.TestObserver {
private TextView mStatusMessage;
private Button mDeviceTestButton;
+ private Button mAccessoryTestButton;
private Button mAbortButton;
private TestCompanion mCurrentTest;
@@ -44,11 +45,13 @@
mStatusMessage = (TextView) findViewById(R.id.status_message);
mDeviceTestButton = (Button) findViewById(R.id.deviceTest);
+ mAccessoryTestButton = (Button) findViewById(R.id.accessoryTest);
mAbortButton = (Button) findViewById(R.id.abort);
mStatusMessage.setText(getString(R.string.status_no_test));
mDeviceTestButton.setOnClickListener(view -> runDeviceTest());
+ mAccessoryTestButton.setOnClickListener(view -> runAccessoryTest());
mAbortButton.setOnClickListener(view -> abortCurrentTest());
}
@@ -60,19 +63,27 @@
}
/**
- * Abort the {@link DeviceTestCompanion}
+ * Run the {@link DeviceTestCompanion}
*/
private void runDeviceTest() {
runTestCompanion(new DeviceTestCompanion(this, this));
}
/**
+ * Run the {@link AccessoryTestCompanion}
+ */
+ private void runAccessoryTest() {
+ runTestCompanion(new AccessoryTestCompanion(this, this));
+ }
+
+ /**
* Run a test.
* @param test The test to run
*/
private void runTestCompanion(@NonNull TestCompanion test) {
mAbortButton.setVisibility(View.VISIBLE);
mDeviceTestButton.setVisibility(View.GONE);
+ mAccessoryTestButton.setVisibility(View.GONE);
mCurrentTest = test;
test.start();
@@ -84,6 +95,7 @@
private void resetUI() {
mAbortButton.setVisibility(View.GONE);
mDeviceTestButton.setVisibility(View.VISIBLE);
+ mAccessoryTestButton.setVisibility(View.VISIBLE);
}
@Override
diff --git a/apps/cts-usb-accessory/Android.mk b/apps/cts-usb-accessory/Android.mk
deleted file mode 100644
index 7699b1a..0000000
--- a/apps/cts-usb-accessory/Android.mk
+++ /dev/null
@@ -1,41 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-# Build for Linux (desktop) host
-ifeq ($(HOST_OS),linux)
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := cts-usb-accessory.c
-
-LOCAL_MODULE := cts-usb-accessory
-
-LOCAL_C_INCLUDES += \
- bionic/libc/kernel/uapi \
- bionic/libc/kernel/android/uapi \
- bionic/libc/kernel/uapi/asm-x86 \
-
-LOCAL_STATIC_LIBRARIES := libusbhost libcutils
-LOCAL_LDLIBS += -lpthread
-LOCAL_CFLAGS := -g -O0
-LOCAL_CXX_STL := none
-
-include $(BUILD_HOST_EXECUTABLE)
-
-endif
diff --git a/apps/cts-usb-accessory/cts-usb-accessory.c b/apps/cts-usb-accessory/cts-usb-accessory.c
deleted file mode 100644
index 0fbfce7..0000000
--- a/apps/cts-usb-accessory/cts-usb-accessory.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <pthread.h>
-#include <time.h>
-
-#include <usbhost/usbhost.h>
-#include <linux/usb/f_accessory.h>
-
-#define USB_CONTROL_READ_TIMEOUT_MS 200
-
-static struct usb_device *sDevice = NULL;
-static int sAfterUnplug = 0;
-static char* sDeviceSerial = NULL;
-
-static void* message_thread(void* arg) {
- int *endpoints = (int *)arg;
- int ret = 0;
- int num = 0;
- char message[50];
-
- while (sDevice && ret >= 0) {
- char buffer[16384];
- ret = usb_device_bulk_transfer(sDevice, endpoints[0], buffer, sizeof(buffer), 1000);
- if (ret < 0 && errno == ETIMEDOUT) {
- ret = 0;
- }
- if (ret > 0) {
- printf("[RECV] ");
- fwrite(buffer, 1, ret, stdout);
- printf("\n");
-
- // Respond by sending a message back
- sprintf(message, "Message from Android accessory #%d", num++);
- printf("[SENT] %s\n", message);
- fflush(stdout);
- usb_device_bulk_transfer(sDevice, endpoints[1], message, strlen(message), 1000);
- }
- }
-
- return NULL;
-}
-
-static void milli_sleep(int millis) {
- struct timespec tm;
-
- tm.tv_sec = 0;
- tm.tv_nsec = millis * 1000000;
- nanosleep(&tm, NULL);
-}
-
-static int send_string(struct usb_device *device, int index, const char* string) {
- int ret = usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
- ACCESSORY_SEND_STRING, 0, index, (void *)string, strlen(string) + 1, 1000);
-
- // some devices can't handle back-to-back requests, so delay a bit
- milli_sleep(10);
- return ret;
-}
-
-static int usb_device_added(const char *devname, void* client_data) {
- struct usb_descriptor_header* desc;
- struct usb_descriptor_iter iter;
- uint16_t vendorId, productId;
- int ret;
- pthread_t th;
-
- struct usb_device *device = usb_device_open(devname);
- if (!device) {
- fprintf(stderr, "usb_device_open failed\n");
- return 0;
- }
-
- char* serial = usb_device_get_serial(device, USB_CONTROL_READ_TIMEOUT_MS);
- if (sDeviceSerial && (!serial || strcmp(sDeviceSerial, serial))) {
- free(serial);
- return 0;
- }
- free(serial);
-
- vendorId = usb_device_get_vendor_id(device);
- productId = usb_device_get_product_id(device);
-
- if (!sDevice && (vendorId == 0x18D1 && (productId == 0x2D00 || productId == 0x2D01))) {
- struct usb_descriptor_header* desc;
- struct usb_descriptor_iter iter;
- struct usb_interface_descriptor *intf = NULL;
- struct usb_endpoint_descriptor *ep1 = NULL;
- struct usb_endpoint_descriptor *ep2 = NULL;
-
- printf("Found Android device in accessory mode (%x:%x)...\n",
- vendorId, productId);
- sDevice = device;
- sDeviceSerial = usb_device_get_serial(sDevice, USB_CONTROL_READ_TIMEOUT_MS);
-
- usb_descriptor_iter_init(device, &iter);
- while ((desc = usb_descriptor_iter_next(&iter)) != NULL && (!intf || !ep1 || !ep2)) {
- if (desc->bDescriptorType == USB_DT_INTERFACE) {
- intf = (struct usb_interface_descriptor *)desc;
- } else if (desc->bDescriptorType == USB_DT_ENDPOINT) {
- if (ep1)
- ep2 = (struct usb_endpoint_descriptor *)desc;
- else
- ep1 = (struct usb_endpoint_descriptor *)desc;
- }
- }
-
- if (!intf) {
- fprintf(stderr, "Interface not found\n");
- exit(1);
- }
- if (!ep1 || !ep2) {
- fprintf(stderr, "Endpoints not found\n");
- exit(1);
- }
-
- if (usb_device_claim_interface(device, intf->bInterfaceNumber)) {
- fprintf(stderr, "usb_device_claim_interface failed errno: %d\n", errno);
- exit(1);
- }
-
- int endpoints[2];
- if ((ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) {
- endpoints[0] = ep1->bEndpointAddress;
- endpoints[1] = ep2->bEndpointAddress;
- } else {
- endpoints[0] = ep2->bEndpointAddress;
- endpoints[1] = ep1->bEndpointAddress;
- }
- pthread_create(&th, NULL, message_thread, (void *)endpoints);
- } else {
- printf("Found possible Android device (%x:%x) "
- "- attempting to switch to accessory mode...\n", vendorId, productId);
-
- uint16_t protocol = 0;
- ret = usb_device_control_transfer(device, USB_DIR_IN | USB_TYPE_VENDOR,
- ACCESSORY_GET_PROTOCOL, 0, 0, &protocol, sizeof(protocol), 1000);
- if (ret == 2) {
- printf("Device supports protocol version %d\n", protocol);
- } else {
- fprintf(stderr, "Failed to read protocol version\n");
- }
-
- ret = (ret < 0) ? ret :
- send_string(device, ACCESSORY_STRING_MANUFACTURER, "Android CTS");
- ret = (ret < 0) ? ret :
- send_string(device, ACCESSORY_STRING_MODEL, "CTS USB Accessory");
- ret = (ret < 0) ? ret :
- send_string(device, ACCESSORY_STRING_DESCRIPTION, "CTS USB Accessory");
- ret = (ret < 0) ? ret :
- send_string(device, ACCESSORY_STRING_VERSION, "1.0");
- ret = (ret < 0) ? ret :
- send_string(device, ACCESSORY_STRING_URI,
- "http://source.android.com/compatibility/cts-intro.html");
- ret = (ret < 0) ? ret :
- send_string(device, ACCESSORY_STRING_SERIAL, "1234567890");
-
- ret = (ret < 0) ? ret :
- usb_device_control_transfer(device, USB_DIR_OUT | USB_TYPE_VENDOR,
- ACCESSORY_START, 0, 0, 0, 0, 1000);
- if (ret < 0) {
- fprintf(stderr, "Failed to start accessory mode\n");
- }
- return 0;
- }
-
- if (device != sDevice)
- usb_device_close(device);
-
- return 0;
-}
-
-static int usb_device_removed(const char *devname, void* client_data) {
- if (sDevice && !strcmp(usb_device_get_name(sDevice), devname)) {
- usb_device_close(sDevice);
- sDevice = NULL;
- if (sAfterUnplug) {
- // exit when we are disconnected the second time
- free(sDeviceSerial);
- return 1;
- } else {
- sAfterUnplug = 1;
- }
- }
- return 0;
-}
-
-
-int main(int argc, char* argv[]) {
- printf("CTS USB Accessory Tester\n");
-
- struct usb_host_context* context = usb_host_init();
- if (!context) {
- fprintf(stderr, "usb_host_init failed");
- return 1;
- }
-
- // this will never return so it is safe to pass thiz directly
- usb_host_run(context, usb_device_added, usb_device_removed, NULL, NULL);
- return 0;
-}
diff --git a/build/config.mk b/build/config.mk
index 2c3d87b..573dc7b 100644
--- a/build/config.mk
+++ b/build/config.mk
@@ -16,24 +16,6 @@
# directory before creating the final CTS distribution.
COMPATIBILITY_TESTCASES_OUT_cts := $(HOST_OUT)/cts/android-cts/testcases
-# Scanners of source files for tests which are then inputed into
-# the XML generator to produce test XMLs.
-CTS_NATIVE_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-native-scanner
-CTS_JAVA_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-java-scanner
-CTS_JAVA_TEST_SCANNER_DOCLET := $(HOST_OUT_JAVA_LIBRARIES)/cts-java-scanner-doclet.jar
-
-# Generator of test XMLs from scanner output.
-CTS_XML_GENERATOR := $(HOST_OUT_EXECUTABLES)/cts-xml-generator
-
-# File indicating which tests should be blacklisted due to problems.
-CTS_EXPECTATIONS := cts/tests/expectations/knownfailures.txt
-
-# File indicating which tests should be blacklisted due to unsupported abi.
-CTS_UNSUPPORTED_ABIS := cts/tests/expectations/unsupportedabis.txt
-
-# Holds the target architecture to build for.
-CTS_TARGET_ARCH := $(TARGET_ARCH)
-
# CTS build rules
BUILD_COMPATIBILITY_SUITE := cts/build/compatibility_test_suite.mk
BUILD_CTS_EXECUTABLE := cts/build/test_executable.mk
diff --git a/build/support_package.mk b/build/support_package.mk
index f6f13d1..e25ba8a 100644
--- a/build/support_package.mk
+++ b/build/support_package.mk
@@ -13,7 +13,7 @@
# limitations under the License.
#
-# Builds a package which is needed by a test package and copies it to CTS
+# Builds a package with dex preopt and proguard disabled
#
# Replace "include $(BUILD_PACKAGE)" with "include $(BUILD_CTS_SUPPORT_PACKAGE)"
#
@@ -23,3 +23,4 @@
LOCAL_PROGUARD_ENABLED := disabled
include $(BUILD_PACKAGE)
+
diff --git a/build/test_executable.mk b/build/test_executable.mk
index 062ddc4..4487777 100644
--- a/build/test_executable.mk
+++ b/build/test_executable.mk
@@ -15,9 +15,9 @@
#
# Builds an executable:
#
-# * Replace "include $(BUILD_EXECUTABLE)"
-# with "include $(BUILD_CTS_EXECUTABLE)"
+# Replace "include $(BUILD_EXECUTABLE)" with "include $(BUILD_CTS_EXECUTABLE)"
#
LOCAL_CXX_STL := libc++
include $(BUILD_EXECUTABLE)
+
diff --git a/build/test_package.mk b/build/test_package.mk
index 92e5ee5..3cec0af 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -13,15 +13,12 @@
# limitations under the License.
#
-# Builds a package and defines a rule to generate the associated test
-# package XML needed by CTS.
+# Builds a package.
#
# Replace "include $(BUILD_PACKAGE)" with "include $(BUILD_CTS_PACKAGE)"
#
-# Disable by default so "m cts" will work in emulator builds
-LOCAL_DEX_PREOPT := false
-LOCAL_PROGUARD_ENABLED := disabled
LOCAL_STATIC_JAVA_LIBRARIES += platform-test-annotations
include $(BUILD_CTS_SUPPORT_PACKAGE)
+
diff --git a/build/test_target_java_library.mk b/build/test_target_java_library.mk
index 354af6c..eb11ef7 100644
--- a/build/test_target_java_library.mk
+++ b/build/test_target_java_library.mk
@@ -13,10 +13,12 @@
# limitations under the License.
#
-# Builds a host library and defines a rule to generate the associated test
-# package XML needed by CTS.
+# Builds a Java library.
#
+
# Disable by default so "m cts" will work in emulator builds
LOCAL_DEX_PREOPT := false
LOCAL_STATIC_JAVA_LIBRARIES += platform-test-annotations
+
include $(BUILD_JAVA_LIBRARY)
+
diff --git a/build/test_target_testng_package.mk b/build/test_target_testng_package.mk
deleted file mode 100644
index 8a0e596..0000000
--- a/build/test_target_testng_package.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#
-# Builds a host library and defines a rule to generate the associated test
-# package XML needed by CTS.
-#
-# Disable by default so "m cts" will work in emulator builds
-LOCAL_DEX_PREOPT := false
-LOCAL_STATIC_JAVA_LIBRARIES += platform-test-annotations
-include $(BUILD_JAVA_LIBRARY)
-include $(BUILD_CTS_MODULE_TEST_CONFIG)
diff --git a/common/host-side/manifest-generator/tests/Android.mk b/common/host-side/manifest-generator/tests/Android.mk
index 2eb5d2f..1601fc8 100644
--- a/common/host-side/manifest-generator/tests/Android.mk
+++ b/common/host-side/manifest-generator/tests/Android.mk
@@ -18,7 +18,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := compatibility-manifest-generator junit
+LOCAL_JAVA_LIBRARIES := compatibility-manifest-generator junit-host
LOCAL_MODULE := compatibility-manifest-generator-tests
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationFailureHandler.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationFailureHandler.java
index e588fbb..dffe3ba 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationFailureHandler.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/InvocationFailureHandler.java
@@ -42,7 +42,7 @@
return (f.exists() && f.length() != 0);
} catch (FileNotFoundException e) {
CLog.e("Could not find invocation failure file for session %s",
- buildHelper.getDirSuffix(buildHelper.getStartTime()));
+ CompatibilityBuildHelper.getDirSuffix(buildHelper.getStartTime()));
CLog.e(e);
return false;
}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanCreator.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanCreator.java
index ff28263..6b9b5e4 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanCreator.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/result/SubPlanCreator.java
@@ -57,12 +57,20 @@
public static final String FAILED = "failed";
public static final String NOT_EXECUTED = "not_executed";
// static mapping of result types to TestStatuses
- private static final Map<String, TestStatus> mStatusMap;
+ private static final Map<String, TestStatus> STATUS_MAP;
static {
Map<String, TestStatus> statusMap = new HashMap<String, TestStatus>();
statusMap.put(PASSED, TestStatus.PASS);
statusMap.put(FAILED, TestStatus.FAIL);
- mStatusMap = Collections.unmodifiableMap(statusMap);
+ STATUS_MAP = Collections.unmodifiableMap(statusMap);
+ }
+
+ // TODO(aaronholden): remove this temporary workaround for b/33090757
+ private static final Set<String> MULTITEST_MODULES;
+ static {
+ Set<String> multiTestModuleSet = new HashSet<String>();
+ multiTestModuleSet.add("CtsDeqpTestCases");
+ MULTITEST_MODULES = Collections.unmodifiableSet(multiTestModuleSet);
}
@Option (name = "name", shortName = 'n', description = "the name of the subplan to create",
@@ -183,10 +191,51 @@
if (mModuleName != null) {
subPlan.addIncludeFilter(new TestFilter(mAbiName, mModuleName, mTestName).toString());
}
+ Set<TestStatus> statusesToRun = getStatusesToRun();
for (IModuleResult module : mResult.getModules()) {
+
+ // TODO(aaronholden): remove this special case from SubPlanCreator, and filter
+ // individual tests only when the module should run. Tracked by b/33211104
+ if (MULTITEST_MODULES.contains(module.getName())) {
+ // cannot check module.isDone() since this value is not accurate for modules
+ // with multiple test configs. If we should run not-executed tests, include module
+ // and exclude tests with status not in mResultTypes.
+ TestFilter moduleFilter =
+ new TestFilter(module.getAbi(), module.getName(), null /*test*/);
+ if (mResultTypes.contains(NOT_EXECUTED)) {
+ subPlan.addIncludeFilter(moduleFilter.toString());
+ for (ICaseResult caseResult : module.getResults()) {
+ for (ITestResult testResult : caseResult.getResults()) {
+ if (!statusesToRun.contains(testResult.getResultStatus())) {
+ TestFilter testExclude = new TestFilter(module.getAbi(),
+ module.getName(), testResult.getFullName());
+ subPlan.addExcludeFilter(testExclude.toString());
+ }
+ }
+ }
+ } else {
+ // not running not-executed tests, only include executed tests
+ if (shouldRunModule(module)) {
+ // at least some executed tests will be included
+ for (ICaseResult caseResult : module.getResults()) {
+ for (ITestResult testResult : caseResult.getResults()) {
+ if (statusesToRun.contains(testResult.getResultStatus())) {
+ TestFilter testInclude = new TestFilter(module.getAbi(),
+ module.getName(), testResult.getFullName());
+ subPlan.addIncludeFilter(testInclude.toString());
+ }
+ }
+ }
+ } else {
+ // no executed tests will be included, so exclude entire module
+ subPlan.addExcludeFilter(moduleFilter.toString());
+ }
+ }
+ continue;
+ }
+
if (shouldRunModule(module)) {
- Set<TestStatus> statusesToRun = getStatusesToRun();
TestFilter moduleInclude =
new TestFilter(module.getAbi(), module.getName(), null /*test*/);
if (shouldRunEntireModule(module)) {
@@ -280,7 +329,7 @@
for (String resultType : mResultTypes) {
// no test status exists for not-executed tests
if (resultType != NOT_EXECUTED) {
- statusesToRun.add(mStatusMap.get(resultType));
+ statusesToRun.add(STATUS_MAP.get(resultType));
}
}
return statusesToRun;
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityHostTestBase.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityHostTestBase.java
new file mode 100644
index 0000000..b2e2a33
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityHostTestBase.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.compatibility.common.tradefed.testtype;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import com.android.annotations.Nullable;
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.ddmlib.Log.LogLevel;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.ddmlib.testrunner.TestResult;
+import com.android.ddmlib.testrunner.TestResult.TestStatus;
+import com.android.ddmlib.testrunner.TestRunResult;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IDeviceTest;
+import com.android.tradefed.util.AbiUtils;
+
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.internal.AssumptionViolatedException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Compatibility host test base class for JUnit4 tests. Enables host-side tests written in JUnit4
+ * to access build and ABI information, as well as a reference to the testing device. The class
+ * includes methods to install and uninstall test packages, as well as methods to run device-side
+ * tests and retrieve their results.
+ */
+public class CompatibilityHostTestBase implements IAbiReceiver, IBuildReceiver, IDeviceTest {
+
+ protected static final String AJUR = "android.support.test.runner.AndroidJUnitRunner";
+
+ /** The build will be used. */
+ protected IBuildInfo mBuild;
+
+ /** The ABI to use. */
+ protected IAbi mAbi;
+
+ /** A reference to the device under test. */
+ protected ITestDevice mDevice;
+
+ /** The test runner used for test apps */
+ private String mRunner;
+
+ @Override
+ public void setAbi(IAbi abi) {
+ mAbi = abi;
+ }
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ // Get the build, this is used to access the APK.
+ mBuild = buildInfo;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ITestDevice getDevice() {
+ return mDevice;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setDevice(ITestDevice device) {
+ mDevice = device;
+ }
+
+ @Before
+ public void baseSetUp() throws Exception {
+ mRunner = AJUR;
+ }
+
+ /**
+ * Set the runner name
+ * @param runner of the device test runner
+ */
+ protected void setRunner(String runner) {
+ mRunner = runner;
+ }
+
+ /**
+ * Get the runner name
+ * @return name of the device test runner
+ */
+ protected String getRunner() {
+ return mRunner;
+ }
+
+ /**
+ * Installs a package on the device
+ * @param fileName the name of the file to install
+ * @param options optional extra arguments to pass. See 'adb shell pm install --help' for
+ * available options
+ * @throws FileNotFoundException if file with filename cannot be found
+ * @throws DeviceNotAvailableException
+ */
+ protected void installPackage(String fileName, String... options)
+ throws FileNotFoundException, DeviceNotAvailableException {
+
+ final List<String> optList = new ArrayList<>(Arrays.asList(options));
+ optList.add(AbiUtils.createAbiFlag(mAbi.getName()));
+ options = optList.toArray(new String[optList.size()]);
+
+ CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuild);
+ File testFile = new File(buildHelper.getTestsDir(), fileName);
+ // Install the APK on the device.
+ String installResult = mDevice.installPackage(testFile, true, options);
+
+ assertNull(String.format("Failed to install %s, Reason: %s", fileName, installResult),
+ installResult);
+ }
+
+ /**
+ * Uninstalls a package on the device
+ * @param pkgName the Android package to uninstall
+ * @return a {@link String} with an error code, or <code>null</code> if success
+ * @throws DeviceNotAvailableException
+ */
+ protected String uninstallPackage(String pkgName) throws DeviceNotAvailableException {
+ return mDevice.uninstallPackage(pkgName);
+ }
+
+ /**
+ * Checks if a package of a given name is installed on the device
+ * @param pkg the name of the package
+ * @return true if the package is found on the device
+ * @throws DeviceNotAvailableException
+ */
+ protected boolean isPackageInstalled(String pkg) throws DeviceNotAvailableException {
+ for (String installedPackage : mDevice.getInstalledPackageNames()) {
+ if (pkg.equals(installedPackage)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void printTestResult(TestRunResult runResult) {
+ for (Map.Entry<TestIdentifier, TestResult> testEntry :
+ runResult.getTestResults().entrySet()) {
+ TestResult testResult = testEntry.getValue();
+ TestStatus testStatus = testResult.getStatus();
+ CLog.logAndDisplay(LogLevel.INFO,
+ "Test " + testEntry.getKey() + ": " + testStatus);
+ if (testStatus != TestStatus.PASSED && testStatus != TestStatus.ASSUMPTION_FAILURE) {
+ CLog.logAndDisplay(LogLevel.WARN, testResult.getStackTrace());
+ }
+ }
+ }
+
+ /**
+ * Runs tests of a given package on the device and reports success.
+ * @param pkgName the name of the package containing tests
+ * @param testClassName the class from which tests should be collected. Tests are collected
+ * from all test classes in the package if null
+ * @return true if at least once test runs and there are no failures
+ * @throws AssertionError if device fails to run instrumentation tests
+ * @throws AssumptionViolatedException if each device test fails an assumption
+ * @throws DeviceNotAvailableException
+ */
+ protected boolean runDeviceTests(String pkgName, @Nullable String testClassName)
+ throws DeviceNotAvailableException {
+ return runDeviceTests(pkgName, testClassName, null /*testMethodName*/);
+ }
+
+ /**
+ * Runs tests of a given package on the device and reports success.
+ * @param pkgName the name of the package containing tests
+ * @param testClassName the class from which tests should be collected. Tests are collected
+ * from all test classes in the package if null
+ * @param testMethodName the test method to run. All tests from the class or package are run
+ * if null
+ * @return true if at least once test runs and there are no failures
+ * @throws AssertionError if device fails to run instrumentation tests
+ * @throws AssumptionViolatedException if each device test fails an assumption
+ * @throws DeviceNotAvailableException
+ */
+ protected boolean runDeviceTests(String pkgName, @Nullable String testClassName,
+ @Nullable String testMethodName)
+ throws DeviceNotAvailableException {
+ TestRunResult runResult = doRunTests(pkgName, testClassName, testMethodName);
+ printTestResult(runResult);
+ // assume not all tests have skipped (and rethrow AssumptionViolatedException if so)
+ Assume.assumeTrue(runResult.getNumTests() != runResult.getNumTestsInState(
+ TestStatus.ASSUMPTION_FAILURE));
+ return !runResult.hasFailedTests() && runResult.getNumTests() > 0;
+ }
+
+ /** Helper method to run tests and return the listener that collected the results. */
+ private TestRunResult doRunTests(
+ String pkgName, String testClassName,
+ String testMethodName) throws DeviceNotAvailableException {
+ RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
+ pkgName, mRunner, mDevice.getIDevice());
+ if (testClassName != null && testMethodName != null) {
+ testRunner.setMethodName(testClassName, testMethodName);
+ } else if (testClassName != null) {
+ testRunner.setClassName(testClassName);
+ }
+
+ CollectingTestListener listener = new CollectingTestListener();
+ assertTrue(mDevice.runInstrumentationTests(testRunner, listener));
+ return listener.getCurrentRunResults();
+ }
+}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
index e8ebcfd..f43249f 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTest.java
@@ -52,6 +52,7 @@
import com.android.tradefed.testtype.IDeviceTest;
import com.android.tradefed.testtype.IRemoteTest;
import com.android.tradefed.testtype.IShardableTest;
+import com.android.tradefed.testtype.IStrictShardableTest;
import com.android.tradefed.util.AbiFormatter;
import com.android.tradefed.util.AbiUtils;
import com.android.tradefed.util.ArrayUtil;
@@ -62,24 +63,26 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* A Test for running Compatibility Suites
*/
@OptionClass(alias = "compatibility")
-public class CompatibilityTest implements IDeviceTest, IShardableTest, IBuildReceiver {
-
+public class CompatibilityTest implements IDeviceTest, IShardableTest, IBuildReceiver,
+ IStrictShardableTest {
public static final String INCLUDE_FILTER_OPTION = "include-filter";
public static final String EXCLUDE_FILTER_OPTION = "exclude-filter";
public static final String SUBPLAN_OPTION = "subplan";
@@ -256,29 +259,35 @@
private String mSystemStatusCheckerConfig = "system-status-checkers";
private int mTotalShards;
+ private Integer mShardIndex = null;
private IModuleRepo mModuleRepo;
private ITestDevice mDevice;
private CompatibilityBuildHelper mBuildHelper;
+ // variables used for local sharding scenario
+ private static CountDownLatch sPreparedLatch;
+ private boolean mIsLocalSharding = false;
+
/**
* Create a new {@link CompatibilityTest} that will run the default list of
* modules.
*/
public CompatibilityTest() {
- this(1 /* totalShards */, new ModuleRepo());
+ this(1 /* totalShards */, new ModuleRepo(), 0);
}
/**
* Create a new {@link CompatibilityTest} that will run a sublist of
* modules.
*/
- public CompatibilityTest(int totalShards, IModuleRepo moduleRepo) {
+ public CompatibilityTest(int totalShards, IModuleRepo moduleRepo, Integer shardIndex) {
if (totalShards < 1) {
throw new IllegalArgumentException(
"Must be at least 1 shard. Given:" + totalShards);
}
mTotalShards = totalShards;
mModuleRepo = moduleRepo;
+ mShardIndex = shardIndex;
}
/**
@@ -311,24 +320,26 @@
@Override
public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
try {
- // Synchronized so only one shard enters and sets up the moduleRepo. When the other
- // shards enter after this, moduleRepo is already initialized so they dont do anything
+ // FIXME: Each shard will do a full initialization which is not optimal. Need a way
+ // to be more specific on what to initialize.
+ List<IModuleDef> modules;
synchronized (mModuleRepo) {
if (!mModuleRepo.isInitialized()) {
setupFilters();
// Initialize the repository, {@link CompatibilityBuildHelper#getTestsDir} can
// throw a {@link FileNotFoundException}
- mModuleRepo.initialize(mTotalShards, mBuildHelper.getTestsDir(), getAbis(),
- mDeviceTokens, mTestArgs, mModuleArgs, mIncludeFilters,
- mExcludeFilters);
+ mModuleRepo.initialize(mTotalShards, mShardIndex, mBuildHelper.getTestsDir(),
+ getAbis(), mDeviceTokens, mTestArgs, mModuleArgs, mIncludeFilters,
+ mExcludeFilters, mBuildHelper.getBuildInfo());
// Add the entire list of modules to the CompatibilityBuildHelper for reporting
mBuildHelper.setModuleIds(mModuleRepo.getModuleIds());
+ } else {
+ CLog.d("ModuleRepo already initialized.");
}
-
+ // Get the tests to run in this shard
+ modules = mModuleRepo.getModules(getDevice().getSerialNumber(), mShardIndex);
}
- // Get the tests to run in this shard
- List<IModuleDef> modules = mModuleRepo.getModules(getDevice().getSerialNumber());
listener = new FailureListener(listener, getDevice(), mBugReportOnFailure,
mLogcatOnFailure, mScreenshotOnFailure, mRebootOnFailure, mMaxLogcatBytes);
@@ -366,26 +377,32 @@
module.setPreparerWhitelist(mPreparerWhitelist);
isPrepared &= (module.prepare(mSkipPreconditions));
}
- mModuleRepo.setPrepared(isPrepared);
-
- int prepAttempt = 1;
- while (!mModuleRepo.isPrepared(MINUTES_PER_PREP_ATTEMPT, TimeUnit.MINUTES)) {
- if (prepAttempt >= NUM_PREP_ATTEMPTS
- || InvocationFailureHandler.hasFailed(mBuildHelper)) {
- CLog.logAndDisplay(LogLevel.ERROR,
- "Incorrect preparation detected, exiting test run from %s",
- mDevice.getSerialNumber());
- return;
- } else {
- CLog.logAndDisplay(LogLevel.INFO,
- "Device %s on standby while all shards complete preparation",
- mDevice.getSerialNumber());
- }
- prepAttempt++;
+ if (!isPrepared) {
+ throw new RuntimeException(String.format("Failed preconditions on %s",
+ mDevice.getSerialNumber()));
}
-
+ if (mIsLocalSharding) {
+ try {
+ sPreparedLatch.countDown();
+ int attempt = 1;
+ while(!sPreparedLatch.await(MINUTES_PER_PREP_ATTEMPT, TimeUnit.MINUTES)) {
+ if (attempt > NUM_PREP_ATTEMPTS ||
+ InvocationFailureHandler.hasFailed(mBuildHelper)) {
+ CLog.logAndDisplay(LogLevel.ERROR,
+ "Incorrect preparation detected, exiting test run from %s",
+ mDevice.getSerialNumber());
+ return;
+ }
+ CLog.logAndDisplay(LogLevel.WARN, "waiting on preconditions");
+ attempt++;
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
// Run the tests
for (int i = 0; i < moduleCount; i++) {
+
IModuleDef module = modules.get(i);
long start = System.currentTimeMillis();
@@ -452,7 +469,7 @@
* @throws DeviceNotAvailableException
*/
Set<IAbi> getAbis() throws DeviceNotAvailableException {
- Set<IAbi> abis = new HashSet<>();
+ Set<IAbi> abis = new LinkedHashSet<>();
Set<String> archAbis = getAbisForBuildTargetArch();
if (mPrimaryAbiRun) {
if (mAbiName == null) {
@@ -722,18 +739,27 @@
if (mShards <= 1) {
return null;
}
-
+ mIsLocalSharding = true;
List<IRemoteTest> shardQueue = new LinkedList<>();
for (int i = 0; i < mShards; i++) {
- CompatibilityTest test = new CompatibilityTest(mShards, mModuleRepo);
- OptionCopier.copyOptionsNoThrow(this, test);
- // Set the shard count because the copy option on the previous line
- // copies over the mShard value
- test.mShards = 0;
+ CompatibilityTest test = (CompatibilityTest) getTestShard(mShards, i);
+ test.mIsLocalSharding = true;
shardQueue.add(test);
}
-
+ sPreparedLatch = new CountDownLatch(shardQueue.size());
return shardQueue;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IRemoteTest getTestShard(int shardCount, int shardIndex) {
+ CompatibilityTest test = new CompatibilityTest(shardCount, mModuleRepo, shardIndex);
+ OptionCopier.copyOptionsNoThrow(this, test);
+ // Set the shard count because the copy option on the previous line
+ // copies over the mShard value
+ test.mShards = 0;
+ return test;
+ }
}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
index cbefc7c..1f6a53e 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/IModuleRepo.java
@@ -15,13 +15,13 @@
*/
package com.android.compatibility.common.tradefed.testtype;
+import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.testtype.IAbi;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
/**
* Interface for accessing tests from the Compatibility repository.
@@ -29,16 +29,6 @@
public interface IModuleRepo {
/**
- * @return true after each shard has prepared successfully.
- */
- boolean isPrepared(long timeout, TimeUnit unit);
-
- /**
- * Indicates to the repo whether a shard is prepared to run.
- */
- void setPrepared(boolean isPrepared);
-
- /**
* @return true if this repository has been initialized.
*/
boolean isInitialized();
@@ -46,14 +36,14 @@
/**
* Initializes the repository.
*/
- void initialize(int shards, File testsDir, Set<IAbi> abis, List<String> deviceTokens,
- List<String> testArgs, List<String> moduleArgs, Set<String> mIncludeFilters,
- Set<String> mExcludeFilters);
+ void initialize(int shards, Integer shardIndex, File testsDir, Set<IAbi> abis,
+ List<String> deviceTokens, List<String> testArgs, List<String> moduleArgs,
+ Set<String> mIncludeFilters, Set<String> mExcludeFilters, IBuildInfo buildInfo);
/**
* @return a {@link Map} of all modules to run on the device referenced by the given serial.
*/
- List<IModuleDef> getModules(String serial);
+ List<IModuleDef> getModules(String serial, int shardIndex);
/**
* @return the number of shards this repo is initialized for.
@@ -61,34 +51,9 @@
int getNumberOfShards();
/**
- * @return the maximum number of modules a shard will run.
+ * @return the modules which do not have token and have not been assigned to a device.
*/
- int getModulesPerShard();
-
- /**
- * @return the {@link Map} of device serials to tokens.
- */
- Map<String, Set<String>> getDeviceTokens();
-
- /**
- * @return the {@link Set} of device serials that have taken their workload.
- */
- Set<String> getSerials();
-
- /**
- * @return the small modules that don't have tokens but have not been assigned to a device.
- */
- List<IModuleDef> getSmallModules();
-
- /**
- * @return the medium modules that don't have tokens but have not been assigned to a device.
- */
- List<IModuleDef> getMediumModules();
-
- /**
- * @return the large modules that don't have tokens but have not been assigned to a device.
- */
- List<IModuleDef> getLargeModules();
+ List<IModuleDef> getNonTokenModules();
/**
* @return the modules which have token and have not been assigned to a device.
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
index 2e71f92..e683de2 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/JarHostTest.java
@@ -16,8 +16,10 @@
package com.android.compatibility.common.tradefed.testtype;
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.Option.Importance;
+import com.android.tradefed.config.OptionCopier;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.ITestInvocationListener;
@@ -25,6 +27,9 @@
import com.android.tradefed.testtype.HostTest;
import com.android.tradefed.testtype.IRemoteTest;
import com.android.tradefed.testtype.IRuntimeHintProvider;
+import com.android.tradefed.util.StreamUtil;
+
+import com.google.common.annotations.VisibleForTesting;
import junit.framework.Test;
@@ -68,9 +73,28 @@
* {@inheritDoc}
*/
@Override
+ protected HostTest createHostTest(Class<?> classObj) {
+ JarHostTest test = new JarHostTest();
+ OptionCopier.copyOptionsNoThrow(this, test);
+ test.setClassName(classObj.getName());
+ return test;
+ }
+
+ /**
+ * Create a {@link CompatibilityBuildHelper} from the build info provided.
+ */
+ @VisibleForTesting
+ CompatibilityBuildHelper createBuildHelper(IBuildInfo info) {
+ return new CompatibilityBuildHelper(info);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
protected List<Class<?>> getClasses() throws IllegalArgumentException {
List<Class<?>> classes = super.getClasses();
- CompatibilityBuildHelper helper = new CompatibilityBuildHelper(getBuild());
+ CompatibilityBuildHelper helper = createBuildHelper(getBuild());
for (String jarName : mJars) {
JarFile jarFile = null;
try {
@@ -108,15 +132,10 @@
}
}
} catch (IOException e) {
- e.printStackTrace();
+ CLog.e(e);
+ throw new RuntimeException(e);
} finally {
- if (jarFile != null) {
- try {
- jarFile.close();
- } catch (IOException e) {
- // Ignored
- }
- }
+ StreamUtil.close(jarFile);
}
}
return classes;
@@ -166,5 +185,4 @@
CLog.d("HostTestListener.testRunEnded(%d, %s)", elapsedTime, metrics.toString());
}
}
-
}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java
index 06cca2f..035b9ea 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleDef.java
@@ -303,7 +303,7 @@
OptionSetter setter = new OptionSetter(target);
setter.setOptionValue(option, value);
} catch (ConfigurationException e) {
- e.printStackTrace();
+ CLog.e(e);
}
}
}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
index 57d5db3..ff8f206 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/testtype/ModuleRepo.java
@@ -15,16 +15,19 @@
*/
package com.android.compatibility.common.tradefed.testtype;
+import com.android.compatibility.common.tradefed.util.LinearPartition;
import com.android.compatibility.common.util.TestFilter;
import com.android.ddmlib.Log.LogLevel;
+import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.ConfigurationException;
import com.android.tradefed.config.ConfigurationFactory;
import com.android.tradefed.config.IConfiguration;
import com.android.tradefed.config.IConfigurationFactory;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IBuildReceiver;
import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.testtype.IShardableTest;
+import com.android.tradefed.testtype.IStrictShardableTest;
import com.android.tradefed.testtype.ITestFileFilterReceiver;
import com.android.tradefed.testtype.ITestFilterReceiver;
import com.android.tradefed.util.AbiUtils;
@@ -45,8 +48,6 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
/**
* Retrieves Compatibility test module definitions from the repository.
@@ -58,60 +59,40 @@
static {
ENDING_MODULES.put("CtsMonkeyTestCases", 1);
}
- private static final long SMALL_TEST = TimeUnit.MINUTES.toMillis(2); // Small tests < 2mins
- private static final long MEDIUM_TEST = TimeUnit.MINUTES.toMillis(10); // Medium tests < 10mins
+ // Synchronization objects for Token Modules.
+ private static int mInitCount = 0;
+ private static Set<IModuleDef> mTokenModuleScheduled;
+ private static Object lock = new Object();
- private int mShards;
- private int mModulesPerShard;
- private int mSmallModulesPerShard;
- private int mMediumModulesPerShard;
- private int mLargeModulesPerShard;
- private int mModuleCount = 0;
- private Set<String> mSerials = new HashSet<>();
+ private int mTotalShards;
+ private Integer mShardIndex;
+
private Map<String, Set<String>> mDeviceTokens = new HashMap<>();
- private Map<String, Map<String, String>> mTestArgs = new HashMap<>();
- private Map<String, Map<String, String>> mModuleArgs = new HashMap<>();
+ private Map<String, Map<String, List<String>>> mTestArgs = new HashMap<>();
+ private Map<String, Map<String, List<String>>> mModuleArgs = new HashMap<>();
private boolean mIncludeAll;
private Map<String, List<TestFilter>> mIncludeFilters = new HashMap<>();
private Map<String, List<TestFilter>> mExcludeFilters = new HashMap<>();
private IConfigurationFactory mConfigFactory = ConfigurationFactory.getInstance();
private volatile boolean mInitialized = false;
- // Whether the modules in this repo are ready to run on their assigned devices.
- // True until explicitly set false in setPrepared().
- private volatile boolean mPrepared = true;
- private CountDownLatch mPreparedLatch;
- // Holds all the small tests waiting to be run.
- private List<IModuleDef> mSmallModules = new ArrayList<>();
- // Holds all the medium tests waiting to be run.
- private List<IModuleDef> mMediumModules = new ArrayList<>();
- // Holds all the large tests waiting to be run.
- private List<IModuleDef> mLargeModules = new ArrayList<>();
// Holds all the tests with tokens waiting to be run. Meaning the DUT must have a specific token.
private List<IModuleDef> mTokenModules = new ArrayList<>();
+ private List<IModuleDef> mNonTokenModules = new ArrayList<>();
/**
* {@inheritDoc}
*/
@Override
public int getNumberOfShards() {
- return mShards;
+ return mTotalShards;
}
/**
- * {@inheritDoc}
+ * Returns the device tokens of this module repo. Exposed for testing.
*/
- @Override
- public int getModulesPerShard() {
- return mModulesPerShard;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Map<String, Set<String>> getDeviceTokens() {
+ protected Map<String, Set<String>> getDeviceTokens() {
return mDeviceTokens;
}
@@ -139,32 +120,8 @@
* {@inheritDoc}
*/
@Override
- public Set<String> getSerials() {
- return mSerials;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public List<IModuleDef> getSmallModules() {
- return mSmallModules;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public List<IModuleDef> getMediumModules() {
- return mMediumModules;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public List<IModuleDef> getLargeModules() {
- return mLargeModules;
+ public List<IModuleDef> getNonTokenModules() {
+ return mNonTokenModules;
}
/**
@@ -181,13 +138,7 @@
@Override
public String[] getModuleIds() {
Set<String> moduleIdSet = new HashSet<>();
- for (IModuleDef moduleDef : mSmallModules) {
- moduleIdSet.add(moduleDef.getId());
- }
- for (IModuleDef moduleDef : mMediumModules) {
- moduleIdSet.add(moduleDef.getId());
- }
- for (IModuleDef moduleDef : mLargeModules) {
+ for (IModuleDef moduleDef : mNonTokenModules) {
moduleIdSet.add(moduleDef.getId());
}
for (IModuleDef moduleDef : mTokenModules) {
@@ -200,28 +151,6 @@
* {@inheritDoc}
*/
@Override
- public boolean isPrepared(long timeout, TimeUnit unit) {
- // returns true only if CountDownLatch reaches zero && no shards have setPrepared to false
- try {
- return (mPreparedLatch.await(timeout, unit)) ? mPrepared : false;
- } catch (InterruptedException e) {
- return false;
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setPrepared(boolean isPrepared) {
- mPrepared &= isPrepared;
- mPreparedLatch.countDown();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
public boolean isInitialized() {
return mInitialized;
}
@@ -230,16 +159,23 @@
* {@inheritDoc}
*/
@Override
- public void initialize(int shards, File testsDir, Set<IAbi> abis, List<String> deviceTokens,
- List<String> testArgs, List<String> moduleArgs, Set<String> includeFilters,
- Set<String> excludeFilters) {
+ public void initialize(int totalShards, Integer shardIndex, File testsDir, Set<IAbi> abis,
+ List<String> deviceTokens, List<String> testArgs, List<String> moduleArgs,
+ Set<String> includeFilters, Set<String> excludeFilters, IBuildInfo buildInfo) {
CLog.d("Initializing ModuleRepo\nShards:%d\nTests Dir:%s\nABIs:%s\nDevice Tokens:%s\n" +
"Test Args:%s\nModule Args:%s\nIncludes:%s\nExcludes:%s",
- shards, testsDir.getAbsolutePath(), abis, deviceTokens, testArgs, moduleArgs,
+ totalShards, testsDir.getAbsolutePath(), abis, deviceTokens, testArgs, moduleArgs,
includeFilters, excludeFilters);
mInitialized = true;
- mShards = shards;
- mPreparedLatch = new CountDownLatch(shards);
+ mTotalShards = totalShards;
+ mShardIndex = shardIndex;
+ synchronized (lock) {
+ mInitCount++;
+ if (mTokenModuleScheduled == null) {
+ mTokenModuleScheduled = new HashSet<>();
+ }
+ }
+
for (String line : deviceTokens) {
String[] parts = line.split(":");
if (parts.length == 2) {
@@ -285,7 +221,7 @@
continue;
}
{
- Map<String, String> args = new HashMap<>();
+ Map<String, List<String>> args = new HashMap<>();
if (mModuleArgs.containsKey(name)) {
args.putAll(mModuleArgs.get(name));
}
@@ -293,28 +229,33 @@
args.putAll(mModuleArgs.get(id));
}
if (args != null && args.size() > 0) {
- for (Entry<String, String> entry : args.entrySet()) {
- config.injectOptionValue(entry.getKey(), entry.getValue());
+ for (Entry<String, List<String>> entry : args.entrySet()) {
+ for (String value : entry.getValue()) {
+ // Collection-type options can be injected with multiple values
+ config.injectOptionValue(entry.getKey(), value);
+ }
}
}
}
List<IRemoteTest> tests = config.getTests();
for (IRemoteTest test : tests) {
String className = test.getClass().getName();
- Map<String, String> args = new HashMap<>();
+ Map<String, List<String>> args = new HashMap<>();
if (mTestArgs.containsKey(className)) {
args.putAll(mTestArgs.get(className));
}
if (args != null && args.size() > 0) {
- for (Entry<String, String> entry : args.entrySet()) {
- config.injectOptionValue(entry.getKey(), entry.getValue());
+ for (Entry<String, List<String>> entry : args.entrySet()) {
+ for (String value : entry.getValue()) {
+ config.injectOptionValue(entry.getKey(), value);
+ }
}
}
addFiltersToTest(test, abi, name);
}
List<IRemoteTest> shardedTests = tests;
- if (mShards > 1) {
- shardedTests = splitShardableTests(tests);
+ if (mTotalShards > 1) {
+ shardedTests = splitShardableTests(tests, buildInfo);
}
for (IRemoteTest test : shardedTests) {
addModuleDef(name, abi, test, pathArg);
@@ -325,20 +266,18 @@
configFile.getName()), e);
}
}
- mModulesPerShard = mModuleCount / shards;
- if (mModuleCount % shards != 0) {
- mModulesPerShard++; // Round up
- }
- mSmallModulesPerShard = mSmallModules.size() / shards;
- mMediumModulesPerShard = mMediumModules.size() / shards;
- mLargeModulesPerShard = mLargeModules.size() / shards;
}
- private static List<IRemoteTest> splitShardableTests(List<IRemoteTest> tests) {
+ private List<IRemoteTest> splitShardableTests(List<IRemoteTest> tests, IBuildInfo buildInfo) {
ArrayList<IRemoteTest> shardedList = new ArrayList<>(tests.size());
for (IRemoteTest test : tests) {
- if (test instanceof IShardableTest) {
- shardedList.addAll(((IShardableTest)test).split());
+ if (test instanceof IBuildReceiver) {
+ ((IBuildReceiver)test).setBuild(buildInfo);
+ }
+ if (mShardIndex != null && test instanceof IStrictShardableTest) {
+ for (int i = 0; i < mTotalShards; i++) {
+ shardedList.add(((IStrictShardableTest)test).getTestShard(mTotalShards, i));
+ }
} else {
shardedList.add(test);
}
@@ -346,7 +285,7 @@
return shardedList;
}
- private static void addFilters(Set<String> stringFilters,
+ private void addFilters(Set<String> stringFilters,
Map<String, List<TestFilter>> filters, Set<IAbi> abis) {
for (String filterString : stringFilters) {
TestFilter filter = TestFilter.createFrom(filterString);
@@ -361,12 +300,12 @@
}
}
- private static void addFilter(String abi, TestFilter filter,
+ private void addFilter(String abi, TestFilter filter,
Map<String, List<TestFilter>> filters) {
getFilter(filters, AbiUtils.createId(abi, filter.getName())).add(filter);
}
- private static List<TestFilter> getFilter(Map<String, List<TestFilter>> filters, String id) {
+ private List<TestFilter> getFilter(Map<String, List<TestFilter>> filters, String id) {
List<TestFilter> fs = filters.get(id);
if (fs == null) {
fs = new ArrayList<>();
@@ -386,14 +325,9 @@
Set<String> tokens = moduleDef.getTokens();
if (tokens != null && !tokens.isEmpty()) {
mTokenModules.add(moduleDef);
- } else if (moduleDef.getRuntimeHint() < SMALL_TEST) {
- mSmallModules.add(moduleDef);
- } else if (moduleDef.getRuntimeHint() < MEDIUM_TEST) {
- mMediumModules.add(moduleDef);
} else {
- mLargeModules.add(moduleDef);
+ mNonTokenModules.add(moduleDef);
}
- mModuleCount++;
}
private void addFiltersToTest(IRemoteTest test, IAbi abi, String name) {
@@ -504,88 +438,49 @@
* {@inheritDoc}
*/
@Override
- public synchronized List<IModuleDef> getModules(String serial) {
- List<IModuleDef> modules = new ArrayList<>(mModulesPerShard);
- Set<String> tokens = mDeviceTokens.get(serial);
- getModulesWithTokens(tokens, modules);
- getModules(modules);
- mSerials.add(serial);
- if (mSerials.size() == mShards) {
- for (IModuleDef def : mTokenModules) {
- CLog.logAndDisplay(LogLevel.WARN,
- String.format("No devices found with %s, running %s on %s",
- def.getTokens(), def.getId(), serial));
- modules.add(def);
- }
- // Add left over modules
- modules.addAll(mLargeModules);
- modules.addAll(mMediumModules);
- modules.addAll(mSmallModules);
- }
+ public List<IModuleDef> getModules(String serial, int shardIndex) {
+ Collections.sort(mNonTokenModules, new ExecutionOrderComparator());
+ List<IModuleDef> modules = getShard(mNonTokenModules, shardIndex, mTotalShards);
+
long estimatedTime = 0;
for (IModuleDef def : modules) {
estimatedTime += def.getRuntimeHint();
}
+
+ // FIXME: Token Modules are the only last part that is not deterministic.
+ synchronized (lock) {
+ // Get tokens from the device
+ Set<String> tokens = mDeviceTokens.get(serial);
+ if (tokens != null && !tokens.isEmpty()) {
+ // if it matches any of the token modules, add them
+ for (IModuleDef def : mTokenModules) {
+ if (!mTokenModuleScheduled.contains(def)) {
+ modules.add(def);
+ CLog.e("Adding %s to scheduled token", def);
+ mTokenModuleScheduled.add(def);
+ }
+ }
+ }
+ if (mInitCount == mTotalShards && mTokenModuleScheduled.size() != mTokenModules.size()) {
+ mTokenModules.removeAll(mTokenModuleScheduled);
+ CLog.e("Could not find any token for %s. Adding to last shard.", mTokenModules);
+ modules.addAll(mTokenModules);
+ }
+ }
Collections.sort(modules, new ExecutionOrderComparator());
CLog.logAndDisplay(LogLevel.INFO, String.format(
- "%s running %s modules, expected to complete in %s",
- serial, modules.size(), TimeUtil.formatElapsedTime(estimatedTime)));
+ "%s running %s modules, expected to complete in %s: %s",
+ serial, modules.size(), TimeUtil.formatElapsedTime(estimatedTime), modules));
return modules;
}
/**
- * Iterates through the remaining tests that require tokens and if the device has all the
- * required tokens it will queue that module to run on that device, else the module gets put
- * back into the list.
+ * Helper to linearly split the list into shards with balanced runtimeHint.
+ * Exposed for testing.
*/
- private void getModulesWithTokens(Set<String> tokens, List<IModuleDef> modules) {
- if (tokens != null) {
- List<IModuleDef> copy = mTokenModules;
- mTokenModules = new ArrayList<>();
- for (IModuleDef module : copy) {
- // If a device has all the tokens required by the module then it can run it.
- if (tokens.containsAll(module.getTokens())) {
- modules.add(module);
- } else {
- mTokenModules.add(module);
- }
- }
- }
- }
-
- /**
- * Adds count modules that do not require tokens, to run on a device.
- */
- private void getModules(List<IModuleDef> modules) {
- // Take the normal share of modules unless the device already has token modules.
- takeModule(mSmallModules, modules, mSmallModulesPerShard - modules.size());
- takeModule(mMediumModules, modules, mMediumModulesPerShard);
- takeModule(mLargeModules, modules, mLargeModulesPerShard);
- // If one bucket runs out, take from any of the others.
- boolean success = true;
- while (success && modules.size() < mModulesPerShard) {
- // Take modules from the buckets until it has enough, or there are no more modules.
- success = takeModule(mSmallModules, modules, 1)
- || takeModule(mMediumModules, modules, 1)
- || takeModule(mLargeModules, modules, 1);
- }
- }
-
- /**
- * Takes count modules from the first list and move it to the second.
- */
- private static boolean takeModule(
- List<IModuleDef> source, List<IModuleDef> destination, int count) {
- if (source.isEmpty()) {
- return false;
- }
- if (count > source.size()) {
- count = source.size();
- }
- for (int i = 0; i < count; i++) {
- destination.add(source.remove(source.size() - 1));// Take from the end of the arraylist.
- }
- return true;
+ protected List<IModuleDef> getShard(List<IModuleDef> fullList, int shardIndex, int totalShard) {
+ List<List<IModuleDef>> res = LinearPartition.split(fullList, totalShard);
+ return res.get(shardIndex);
}
/**
@@ -610,23 +505,31 @@
return modules;
}
- private static void putArgs(List<String> args, Map<String, Map<String, String>> argsMap) {
+ private static void putArgs(List<String> args,
+ Map<String, Map<String, List<String>>> argsMap) {
for (String arg : args) {
String[] parts = arg.split(":");
String target = parts[0];
String key = parts[1];
String value = parts[2];
- Map<String, String> map = argsMap.get(target);
+ Map<String, List<String>> map = argsMap.get(target);
if (map == null) {
map = new HashMap<>();
argsMap.put(target, map);
}
- map.put(key, value);
+ List<String> valueList = map.get(key);
+ if (valueList == null) {
+ valueList = new ArrayList<>();
+ map.put(key, valueList);
+ }
+ valueList.add(value);
}
}
+ /**
+ * Sort by name and use runtimeHint for separation, shortest test first.
+ */
private static class ExecutionOrderComparator implements Comparator<IModuleDef> {
-
@Override
public int compare(IModuleDef def1, IModuleDef def2) {
int value1 = 0;
@@ -638,9 +541,21 @@
value2 = ENDING_MODULES.get(def2.getName());
}
if (value1 == 0 && value2 == 0) {
- return (int) Math.signum(def2.getRuntimeHint() - def1.getRuntimeHint());
+ int time = (int) Math.signum(def1.getRuntimeHint() - def2.getRuntimeHint());
+ if (time == 0) {
+ return def1.getName().compareTo(def2.getName());
+ }
+ return time;
}
return (int) Math.signum(value1 - value2);
}
}
+
+ /**
+ * Reset some module repo variable. Exposed for testing.
+ */
+ protected void resetModuleRepo() {
+ mInitCount = 0;
+ mTokenModuleScheduled = null;
+ }
}
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/CollectorUtil.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/CollectorUtil.java
index c488f51..2390d9e 100644
--- a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/CollectorUtil.java
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/CollectorUtil.java
@@ -139,7 +139,7 @@
* Helper function to reformat JSON string.
*
* @param jsonString
- * @return
+ * @return the reformatted JSON string.
*/
public static String reformatJsonString(String jsonString) {
StringBuilder newJsonBuilder = new StringBuilder();
diff --git a/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/LinearPartition.java b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/LinearPartition.java
new file mode 100644
index 0000000..df91e57
--- /dev/null
+++ b/common/host-side/tradefed/src/com/android/compatibility/common/tradefed/util/LinearPartition.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.compatibility.common.tradefed.util;
+
+import com.android.compatibility.common.tradefed.testtype.IModuleDef;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper for the shard splitting. Split linearly a list into N sublist with
+ * approximately the same weight.
+ * TODO: Can be generalized for any weighted objects.
+ */
+public class LinearPartition {
+
+ /**
+ * Split a list of {@link IModuleDef} into k sub list based on the runtime hint.
+ *
+ * @param seq the full list of {@link IModuleDef} to be splitted
+ * @param k the number of sub list we need.
+ * @return the List of sublist.
+ */
+ public static List<List<IModuleDef>> split(List<IModuleDef> seq, int k) {
+ ArrayList<List<IModuleDef>> result = new ArrayList<>();
+
+ if (k <= 0) {
+ ArrayList<IModuleDef> partition = new ArrayList<>();
+ partition.addAll(seq);
+ result.add(partition);
+ return result;
+ }
+
+ int n = seq.size() - 1;
+
+ if (k > n) {
+ for (IModuleDef value : seq) {
+ ArrayList<IModuleDef> partition = new ArrayList<>();
+ partition.add(value);
+ result.add(partition);
+ }
+ return result;
+ }
+
+ int[][] table = buildPartitionTable(seq, k);
+ k = k - 2;
+
+ while (k >= 0) {
+ ArrayList<IModuleDef> partition = new ArrayList<>();
+
+ for (int i = table[n - 1][k] + 1; i < n + 1; i++) {
+ partition.add(seq.get(i));
+ }
+
+ result.add(0, partition);
+ n = table[n - 1][k];
+ k = k - 1;
+ }
+
+ ArrayList<IModuleDef> partition = new ArrayList<>();
+
+ for (int i = 0; i < n + 1; i++) {
+ partition.add(seq.get(i));
+ }
+
+ result.add(0, partition);
+
+ return result;
+ }
+
+ /**
+ * Internal helper to build the partition table of the linear distribution used for splitting.
+ */
+ private static int[][] buildPartitionTable(List<IModuleDef> seq, int k) {
+ int n = seq.size();
+ float[][] table = new float[n][k];
+ int[][] solution = new int[n - 1][k - 1];
+
+ for (int i = 0; i < n; i++) {
+ table[i][0] = seq.get(i).getRuntimeHint() + ((i > 0) ? (table[i - 1][0]) : 0);
+ }
+
+ for (int j = 0; j < k; j++) {
+ table[0][j] = seq.get(0).getRuntimeHint();
+ }
+
+ for (int i = 1; i < n; i++) {
+ for (int j = 1; j < k; j++) {
+ table[i][j] = Integer.MAX_VALUE;
+ for (int x = 0; x < i; x++) {
+ float cost = Math.max(table[x][j - 1], table[i][0] - table[x][0]);
+ if (table[i][j] > cost) {
+ table[i][j] = cost;
+ solution[i - 1][j - 1] = x;
+ }
+ }
+ }
+ }
+
+ return solution;
+ }
+}
diff --git a/common/host-side/tradefed/tests/Android.mk b/common/host-side/tradefed/tests/Android.mk
index 17bdd50..6bc8bc9 100644
--- a/common/host-side/tradefed/tests/Android.mk
+++ b/common/host-side/tradefed/tests/Android.mk
@@ -34,6 +34,7 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_JAVA_RESOURCE_DIRS := res
LOCAL_MODULE := compatibility-tradefed-tests
diff --git a/common/host-side/tradefed/tests/res/testtype/testJar1.jar b/common/host-side/tradefed/tests/res/testtype/testJar1.jar
new file mode 100644
index 0000000..50d5bd2
--- /dev/null
+++ b/common/host-side/tradefed/tests/res/testtype/testJar1.jar
Binary files differ
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java
index dcdede0..4484d49 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/UnitTests.java
@@ -25,7 +25,9 @@
import com.android.compatibility.common.tradefed.result.SubPlanCreatorTest;
import com.android.compatibility.common.tradefed.targetprep.PropertyCheckTest;
import com.android.compatibility.common.tradefed.targetprep.SettingsPreparerTest;
+import com.android.compatibility.common.tradefed.testtype.CompatibilityHostTestBaseTest;
import com.android.compatibility.common.tradefed.testtype.CompatibilityTestTest;
+import com.android.compatibility.common.tradefed.testtype.JarHostTestTest;
import com.android.compatibility.common.tradefed.testtype.ModuleDefTest;
import com.android.compatibility.common.tradefed.testtype.ModuleRepoTest;
import com.android.compatibility.common.tradefed.testtype.SubPlanTest;
@@ -67,7 +69,9 @@
addTestSuite(SettingsPreparerTest.class);
// testtype
+ addTestSuite(CompatibilityHostTestBaseTest.class);
addTestSuite(CompatibilityTestTest.class);
+ addTestSuite(JarHostTestTest.class);
addTestSuite(ModuleDefTest.class);
addTestSuite(ModuleRepoTest.class);
addTestSuite(SubPlanTest.class);
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityHostTestBaseTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityHostTestBaseTest.java
new file mode 100644
index 0000000..2724df6
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityHostTestBaseTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.compatibility.common.tradefed.testtype;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.JUnit4ResultForwarder;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+import com.android.tradefed.testtype.IBuildReceiver;
+import com.android.tradefed.testtype.IDeviceTest;
+
+import junit.framework.TestCase;
+
+import org.easymock.EasyMock;
+
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Request;
+import org.junit.runner.Runner;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.util.Collections;
+
+/**
+ * Tests for the CompatibilityHostTestBase class.
+ */
+public class CompatibilityHostTestBaseTest extends TestCase {
+
+ private static final String DEVICE_TEST_PKG = "com.android.foo";
+
+ @RunWith(DeviceJUnit4ClassRunner.class)
+ public static class MockTest extends CompatibilityHostTestBase {
+
+ @Test
+ public void testRunDeviceTests() throws Exception {
+ runDeviceTests(DEVICE_TEST_PKG, null, null);
+ }
+
+ }
+
+ public void testRunMockDeviceTests() throws Exception {
+ final TestIdentifier testRunDeviceTests =
+ new TestIdentifier(MockTest.class.getName(), "testRunDeviceTests");
+
+ ITestInvocationListener listener = EasyMock.createMock(ITestInvocationListener.class);
+ ITestDevice device = EasyMock.createMock(ITestDevice.class);
+
+ listener.testStarted(testRunDeviceTests);
+ EasyMock.expect(device.getIDevice()).andReturn(EasyMock.createMock(IDevice.class)).once();
+ EasyMock.expect(device.runInstrumentationTests((RemoteAndroidTestRunner)
+ EasyMock.anyObject(), (CollectingTestListener) EasyMock.anyObject())).andReturn(
+ true).once();
+ listener.testEnded(testRunDeviceTests, Collections.emptyMap());
+ EasyMock.replay(listener, device);
+
+ JUnitCore runnerCore = new JUnitCore();
+ runnerCore.addListener(new JUnit4ResultForwarder(listener));
+ Runner checkRunner = Request.aClass(MockTest.class).getRunner();
+ ((IDeviceTest) checkRunner).setDevice(device);
+ ((IBuildReceiver) checkRunner).setBuild(EasyMock.createMock(IBuildInfo.class));
+ ((IAbiReceiver) checkRunner).setAbi(EasyMock.createMock(IAbi.class));
+ runnerCore.run(checkRunner);
+ EasyMock.verify(listener, device);
+ }
+
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
index 89c3c76..927b30b 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/CompatibilityTestTest.java
@@ -23,11 +23,11 @@
import junit.framework.TestCase;
-import org.easymock.EasyMock;
-
import java.util.HashSet;
import java.util.Set;
+import org.easymock.EasyMock;
+
/**
* Test class for {@link CompatibilityTest}
*/
@@ -164,4 +164,20 @@
}
EasyMock.verify(mMockDevice);
}
+
+ /**
+ * Test {@link CompatibilityTest#split()} when a shard number is specified.
+ */
+ public void testSplit() throws Exception {
+ OptionSetter setter = new OptionSetter(mTest);
+ setter.setOptionValue("shards", "4");
+ assertEquals(4, mTest.split().size());
+ }
+
+ /**
+ * Test {@link CompatibilityTest#split()} when no shard number is specified.
+ */
+ public void testSplit_notShardable() throws Exception {
+ assertNull(mTest.split());
+ }
}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/JarHostTestTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/JarHostTestTest.java
new file mode 100644
index 0000000..cf5e214
--- /dev/null
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/JarHostTestTest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.compatibility.common.tradefed.testtype;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.OptionSetter;
+import com.android.tradefed.testtype.HostTest;
+import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.testtype.StubTest;
+import com.android.tradefed.util.FileUtil;
+
+import junit.framework.TestCase;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * Unit tests for {@link JarHostTest}.
+ */
+public class JarHostTestTest extends TestCase {
+
+ private static final String TEST_JAR1 = "/testtype/testJar1.jar";
+ private JarHostTest mTest;
+ private File mTestDir = null;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTest = new JarHostTest();
+ mTestDir = FileUtil.createTempDir("jarhostest");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ FileUtil.recursiveDelete(mTestDir);
+ super.tearDown();
+ }
+
+ /**
+ * Helper to read a file from the res/testtype directory and return it.
+ *
+ * @param filename the name of the file in the res/testtype directory
+ * @param parentDir dir where to put the jar. Null if in default tmp directory.
+ * @return the extracted jar file.
+ */
+ protected File getJarResource(String filename, File parentDir) throws IOException {
+ InputStream jarFileStream = getClass().getResourceAsStream(filename);
+ File jarFile = FileUtil.createTempFile("test", ".jar", parentDir);
+ FileUtil.writeToFile(jarFileStream, jarFile);
+ return jarFile;
+ }
+
+ /**
+ * Test class, we have to annotate with full org.junit.Test to avoid name collision in import.
+ */
+ @RunWith(JUnit4.class)
+ public static class Junit4TestClass {
+ public Junit4TestClass() {}
+ @org.junit.Test
+ public void testPass1() {}
+ }
+
+ /**
+ * Test class, we have to annotate with full org.junit.Test to avoid name collision in import.
+ */
+ @RunWith(JUnit4.class)
+ public static class Junit4TestClass2 {
+ public Junit4TestClass2() {}
+ @org.junit.Test
+ public void testPass2() {}
+ }
+
+ /**
+ * Test that {@link JarHostTest#split()} inherited from {@link HostTest} is still good.
+ */
+ public void testSplit_withoutJar() throws Exception {
+ OptionSetter setter = new OptionSetter(mTest);
+ setter.setOptionValue("class", "com.android.compatibility.common.tradefed.testtype."
+ + "JarHostTestTest$Junit4TestClass");
+ setter.setOptionValue("class", "com.android.compatibility.common.tradefed.testtype."
+ + "JarHostTestTest$Junit4TestClass2");
+ List<IRemoteTest> res = (List<IRemoteTest>)mTest.split();
+ assertEquals(2, res.size());
+ assertTrue(res.get(0) instanceof JarHostTest);
+ assertTrue(res.get(1) instanceof JarHostTest);
+ }
+
+ /**
+ * Test that {@link JarHostTest#split()} can split classes coming from a jar.
+ */
+ public void testSplit_withJar() throws Exception {
+ File testJar = getJarResource(TEST_JAR1, mTestDir);
+ mTest = new JarHostTest() {
+ @Override
+ CompatibilityBuildHelper createBuildHelper(IBuildInfo info) {
+ return new CompatibilityBuildHelper(info) {
+ @Override
+ public File getTestsDir() throws FileNotFoundException {
+ return mTestDir;
+ }
+ };
+ }
+ };
+ OptionSetter setter = new OptionSetter(mTest);
+ setter.setOptionValue("jar", testJar.getName());
+ List<IRemoteTest> res = (List<IRemoteTest>)mTest.split();
+ assertEquals(2, res.size());
+ assertTrue(res.get(0) instanceof JarHostTest);
+ assertEquals("[android.ui.cts.TaskSwitchingTest]",
+ ((JarHostTest)res.get(0)).getClassNames().toString());
+ assertTrue(res.get(1) instanceof JarHostTest);
+ assertEquals("[android.ui.cts.InstallTimeTest]",
+ ((JarHostTest)res.get(1)).getClassNames().toString());
+ }
+
+ /**
+ * Test that {@link JarHostTest#getTestShard(int, int)} can split classes coming from a jar.
+ */
+ public void testGetTestShard_withJar() throws Exception {
+ File testJar = getJarResource(TEST_JAR1, mTestDir);
+ mTest = new JarHostTest() {
+ @Override
+ CompatibilityBuildHelper createBuildHelper(IBuildInfo info) {
+ return new CompatibilityBuildHelper(info) {
+ @Override
+ public File getTestsDir() throws FileNotFoundException {
+ return mTestDir;
+ }
+ };
+ }
+ };
+ OptionSetter setter = new OptionSetter(mTest);
+ setter.setOptionValue("jar", testJar.getName());
+ IRemoteTest shard1 = mTest.getTestShard(3, 0);
+ assertTrue(shard1 instanceof JarHostTest);
+ assertEquals("[android.ui.cts.TaskSwitchingTest]",
+ ((JarHostTest)shard1).getClassNames().toString());
+ IRemoteTest shard2 = mTest.getTestShard(3, 1);
+ assertTrue(shard2 instanceof JarHostTest);
+ assertEquals("[android.ui.cts.InstallTimeTest]",
+ ((JarHostTest)shard2).getClassNames().toString());
+ // Not enough class for a real 3rd shard, so it's a stub placeholder instead.
+ IRemoteTest shard3 = mTest.getTestShard(3, 2);
+ assertTrue(shard3 instanceof StubTest);
+ }
+}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java
index 46958b8..c939949 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ModuleRepoTest.java
@@ -17,24 +17,34 @@
package com.android.compatibility.common.tradefed.testtype;
import com.android.compatibility.common.tradefed.testtype.ModuleRepo.ConfigFilter;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.targetprep.ITargetPreparer;
import com.android.tradefed.testtype.Abi;
import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.testtype.IShardableTest;
+import com.android.tradefed.testtype.IRuntimeHintProvider;
+import com.android.tradefed.testtype.IStrictShardableTest;
+import com.android.tradefed.testtype.ITestCollector;
+import com.android.tradefed.testtype.ITestFilterReceiver;
import com.android.tradefed.util.AbiUtils;
import com.android.tradefed.util.FileUtil;
import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
public class ModuleRepoTest extends TestCase {
@@ -54,7 +64,7 @@
private static final String SERIAL2 = "def";
private static final String SERIAL3 = "ghi";
private static final Set<String> SERIALS = new HashSet<>();
- private static final Set<IAbi> ABIS = new HashSet<>();
+ private static final Set<IAbi> ABIS = new LinkedHashSet<>();
private static final List<String> DEVICE_TOKENS = new ArrayList<>();
private static final List<String> TEST_ARGS= new ArrayList<>();
private static final List<String> MODULE_ARGS = new ArrayList<>();
@@ -101,14 +111,16 @@
FILES.add(String.format(FILENAME, MODULE_NAME_B));
FILES.add(String.format(FILENAME, MODULE_NAME_C));
}
- private IModuleRepo mRepo;
+ private ModuleRepo mRepo;
private File mTestsDir;
private File mRoot = null;
+ private IBuildInfo mMockBuildInfo;
@Override
public void setUp() throws Exception {
mTestsDir = setUpConfigs();
mRepo = new ModuleRepo();
+ mMockBuildInfo = EasyMock.createMock(IBuildInfo.class);
}
private File setUpConfigs() throws IOException {
@@ -137,6 +149,7 @@
public void tearDown() throws Exception {
tearDownConfigs(mTestsDir);
FileUtil.recursiveDelete(mRoot);
+ mRepo.resetModuleRepo();
}
private void tearDownConfigs(File testsDir) {
@@ -144,34 +157,75 @@
}
public void testInitialization() throws Exception {
- mRepo.initialize(3, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
- EXCLUDES);
+ mRepo.initialize(3, null, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
+ EXCLUDES, mMockBuildInfo);
assertTrue("Should be initialized", mRepo.isInitialized());
assertEquals("Wrong number of shards", 3, mRepo.getNumberOfShards());
- assertEquals("Wrong number of modules per shard", 2, mRepo.getModulesPerShard());
Map<String, Set<String>> deviceTokens = mRepo.getDeviceTokens();
assertEquals("Wrong number of devices with tokens", 1, deviceTokens.size());
Set<String> tokens = deviceTokens.get(SERIAL3);
assertEquals("Wrong number of tokens", 1, tokens.size());
assertTrue("Unexpected device token", tokens.contains(FOOBAR_TOKEN));
- assertEquals("Wrong number of modules", 0, mRepo.getLargeModules().size());
- assertEquals("Wrong number of modules", 0, mRepo.getMediumModules().size());
- assertEquals("Wrong number of modules", 4, mRepo.getSmallModules().size());
+ assertEquals("Wrong number of modules", 4, mRepo.getNonTokenModules().size());
List<IModuleDef> tokenModules = mRepo.getTokenModules();
assertEquals("Wrong number of modules with tokens", 2, tokenModules.size());
- List<IModuleDef> serial1Modules = mRepo.getModules(SERIAL1);
- assertEquals("Wrong number of modules", 2, serial1Modules.size());
- List<IModuleDef> serial2Modules = mRepo.getModules(SERIAL2);
- assertEquals("Wrong number of modules", 2, serial2Modules.size());
- List<IModuleDef> serial3Modules = mRepo.getModules(SERIAL3);
- assertEquals("Wrong number of modules", 2, serial3Modules.size());
- // Serial 3 should have the modules with tokens
- for (IModuleDef module : serial3Modules) {
- assertEquals("Wrong module", MODULE_NAME_C, module.getName());
- }
- Set<String> serials = mRepo.getSerials();
- assertEquals("Wrong number of serials", 3, serials.size());
- assertTrue("Unexpected device serial", serials.containsAll(SERIALS));
+ }
+
+ public void testGetModules() throws Exception {
+ mRepo.initialize(1, null, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
+ EXCLUDES, mMockBuildInfo);
+ assertTrue("Should be initialized", mRepo.isInitialized());
+ assertEquals("Wrong number of tokens", 2, mRepo.getTokenModules().size());
+ assertEquals("Wrong number of tokens", 4, mRepo.getNonTokenModules().size());
+ }
+
+ /**
+ * Test sharding with 2 shards of the 4 non token modules.
+ */
+ public void testGetModulesSharded() throws Exception {
+ mRepo.initialize(2, null, mTestsDir, ABIS, new ArrayList<String>(), TEST_ARGS, MODULE_ARGS,
+ INCLUDES, EXCLUDES, mMockBuildInfo);
+ assertTrue("Should be initialized", mRepo.isInitialized());
+ assertEquals("Wrong number of tokens", 2, mRepo.getTokenModules().size());
+ assertEquals("Wrong number of tokens", 4, mRepo.getNonTokenModules().size());
+ List<IModuleDef> shard1 = mRepo.getModules(SERIAL1, 0);
+ assertEquals(2, shard1.size());
+ assertEquals("armeabi-v7a FooModuleA", shard1.get(0).getId());
+ assertEquals("arm64-v8a FooModuleA", shard1.get(1).getId());
+ List<IModuleDef> shard2 = mRepo.getModules(SERIAL2, 1);
+ assertEquals(2, shard2.size());
+ assertEquals("armeabi-v7a FooModuleB", shard2.get(0).getId());
+ assertEquals("arm64-v8a FooModuleB", shard2.get(1).getId());
+ }
+
+ /**
+ * Test sharding with 4 shards of the 6 non token modules.
+ */
+ public void testGetModulesSharded_uneven() throws Exception {
+ createConfig(mTestsDir, "FooModuleD", null);
+ mRepo.initialize(4, null, mTestsDir, ABIS, new ArrayList<String>(), TEST_ARGS, MODULE_ARGS,
+ INCLUDES, EXCLUDES, mMockBuildInfo);
+ assertTrue("Should be initialized", mRepo.isInitialized());
+ assertEquals("Wrong number of tokens", 2, mRepo.getTokenModules().size());
+ assertEquals("Wrong number of tokens", 6, mRepo.getNonTokenModules().size());
+
+ List<IModuleDef> shard1 = mRepo.getModules(SERIAL1, 0);
+ assertEquals(1, shard1.size());
+ assertEquals("armeabi-v7a FooModuleA", shard1.get(0).getId());
+
+ List<IModuleDef> shard2 = mRepo.getModules(SERIAL2, 1);
+ assertEquals(1, shard2.size());
+ assertEquals("arm64-v8a FooModuleA", shard2.get(0).getId());
+
+ List<IModuleDef> shard3 = mRepo.getModules(SERIAL3, 2);
+ assertEquals(2, shard3.size());
+ assertEquals("armeabi-v7a FooModuleB", shard3.get(0).getId());
+ assertEquals("arm64-v8a FooModuleB", shard3.get(1).getId());
+
+ List<IModuleDef> shard4 = mRepo.getModules(SERIAL2, 3);
+ assertEquals(2, shard4.size());
+ assertEquals("armeabi-v7a FooModuleD", shard4.get(0).getId());
+ assertEquals("arm64-v8a FooModuleD", shard4.get(1).getId());
}
public void testConfigFilter() throws Exception {
@@ -189,9 +243,9 @@
Set<String> excludeFilters = new HashSet<>();
excludeFilters.add(ID_A_32);
excludeFilters.add(MODULE_NAME_B);
- mRepo.initialize(1, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, includeFilters,
- excludeFilters);
- List<IModuleDef> modules = mRepo.getModules(SERIAL1);
+ mRepo.initialize(1, null, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS,
+ includeFilters, excludeFilters, mMockBuildInfo);
+ List<IModuleDef> modules = mRepo.getModules(SERIAL1, 0);
assertEquals("Incorrect number of modules", 1, modules.size());
IModuleDef module = modules.get(0);
assertEquals("Incorrect ID", ID_A_64, module.getId());
@@ -199,9 +253,9 @@
}
public void testParsing() throws Exception {
- mRepo.initialize(1, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
- EXCLUDES);
- List<IModuleDef> modules = mRepo.getModules(SERIAL3);
+ mRepo.initialize(1, null, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
+ EXCLUDES, mMockBuildInfo);
+ List<IModuleDef> modules = mRepo.getModules(SERIAL3, 0);
Set<String> idSet = new HashSet<>();
for (IModuleDef module : modules) {
idSet.add(module.getId());
@@ -234,54 +288,97 @@
abis.add(new Abi(ABI_64, "64"));
ArrayList<String> emptyList = new ArrayList<>();
- mRepo.initialize(3, mTestsDir, abis, DEVICE_TOKENS, emptyList, emptyList, INCLUDES,
- EXCLUDES);
+ mRepo.initialize(3, 0, mTestsDir, abis, DEVICE_TOKENS, emptyList, emptyList, INCLUDES,
+ EXCLUDES, mMockBuildInfo);
List<IModuleDef> modules = new ArrayList<>();
- modules.addAll(mRepo.getLargeModules());
- modules.addAll(mRepo.getMediumModules());
- modules.addAll(mRepo.getSmallModules());
+ modules.addAll(mRepo.getNonTokenModules());
modules.addAll(mRepo.getTokenModules());
int shardableCount = 0;
for (IModuleDef def : modules) {
IRemoteTest test = def.getTest();
- if (test instanceof IShardableTest) {
+ if (test instanceof IStrictShardableTest) {
shardableCount++;
}
}
- assertEquals("Shards wrong", 3*3, shardableCount);
+ assertEquals("Shards wrong", 9, shardableCount);
}
public void testGetModuleIds() {
- mRepo.initialize(3, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
- EXCLUDES);
+ mRepo.initialize(3, null, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
+ EXCLUDES, mMockBuildInfo);
assertTrue("Should be initialized", mRepo.isInitialized());
assertArrayEquals(EXPECTED_MODULE_IDS, mRepo.getModuleIds());
}
- public void testIsPrepared() {
- mRepo.initialize(3, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
- EXCLUDES);
- assertTrue("Should be initialized", mRepo.isInitialized());
- mRepo.setPrepared(true);
- mRepo.setPrepared(true);
- mRepo.setPrepared(true); // each shard should call setPrepared() once
- assertTrue(mRepo.isPrepared(0, TimeUnit.MINUTES));
- }
-
- public void testIsNotPrepared() {
- mRepo.initialize(3, mTestsDir, ABIS, DEVICE_TOKENS, TEST_ARGS, MODULE_ARGS, INCLUDES,
- EXCLUDES);
- assertTrue("Should be initialized", mRepo.isInitialized());
- mRepo.setPrepared(true);
- mRepo.setPrepared(false); // mRepo should return false for setPrepared() after third call
- mRepo.setPrepared(true);
- assertFalse(mRepo.isPrepared(0, TimeUnit.MINUTES));
- }
-
private void assertArrayEquals(Object[] expected, Object[] actual) {
assertEquals(Arrays.asList(expected), Arrays.asList(actual));
}
+
+ /**
+ * Test class to provide runtimeHint.
+ */
+ private class TestRuntime implements IRemoteTest, IRuntimeHintProvider, IAbiReceiver,
+ ITestCollector, ITestFilterReceiver {
+ public long runtimeHint = 0l;
+ @Override
+ public long getRuntimeHint() {
+ return runtimeHint;
+ }
+ // ignore all the other calls
+ @Override
+ public void run(ITestInvocationListener arg0) throws DeviceNotAvailableException {}
+ @Override
+ public void addAllExcludeFilters(Set<String> arg0) {}
+ @Override
+ public void addAllIncludeFilters(Set<String> arg0) {}
+ @Override
+ public void addExcludeFilter(String arg0) {}
+ @Override
+ public void addIncludeFilter(String arg0) {}
+ @Override
+ public void setCollectTestsOnly(boolean arg0) {}
+ @Override
+ public void setAbi(IAbi arg0) {}
+ }
+
+ /**
+ * Balance the load of runtime of the modules for the same runtimehint everywhere.
+ */
+ public void testGetshard_allSameRuntime() throws Exception {
+ List<IModuleDef> testList = new ArrayList<>();
+ TestRuntime test1 = new TestRuntime();
+ test1.runtimeHint = 100l;
+ IModuleDef mod1 = new ModuleDef("test1", new Abi("arm", "32"), test1,
+ new ArrayList<ITargetPreparer>());
+ testList.add(mod1);
+ TestRuntime test2 = new TestRuntime();
+ test2.runtimeHint = 100l;
+ IModuleDef mod2 = new ModuleDef("test2", new Abi("arm", "32"), test2,
+ new ArrayList<ITargetPreparer>());
+ testList.add(mod2);
+ TestRuntime test3 = new TestRuntime();
+ test3.runtimeHint = 100l;
+ IModuleDef mod3 = new ModuleDef("test3", new Abi("arm", "32"), test3,
+ new ArrayList<ITargetPreparer>());
+ testList.add(mod3);
+ TestRuntime test4 = new TestRuntime();
+ test4.runtimeHint = 100l;
+ IModuleDef mod4 = new ModuleDef("test4", new Abi("arm", "32"), test4,
+ new ArrayList<ITargetPreparer>());
+ testList.add(mod4);
+ // if we don't shard everything is in one shard.
+ List<IModuleDef> res = mRepo.getShard(testList, 0, 1);
+ assertEquals(4, res.size());
+ res = mRepo.getShard(testList, 0, 2);
+ assertEquals(2, res.size());
+ assertEquals(mod1, res.get(0));
+ assertEquals(mod2, res.get(1));
+ res = mRepo.getShard(testList, 1, 2);
+ assertEquals(2, res.size());
+ assertEquals(mod3, res.get(0));
+ assertEquals(mod4, res.get(1));
+ }
}
diff --git a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java
index f4db091..1a63b03 100644
--- a/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java
+++ b/common/host-side/tradefed/tests/src/com/android/compatibility/common/tradefed/testtype/ShardableTestStub.java
@@ -25,6 +25,7 @@
import com.android.tradefed.testtype.IRemoteTest;
import com.android.tradefed.testtype.IRuntimeHintProvider;
import com.android.tradefed.testtype.IShardableTest;
+import com.android.tradefed.testtype.IStrictShardableTest;
import com.android.tradefed.testtype.ITestCollector;
import com.android.tradefed.testtype.ITestFilterReceiver;
@@ -33,7 +34,8 @@
import java.util.Set;
public class ShardableTestStub implements IRemoteTest, IShardableTest, IBuildReceiver,
- IAbiReceiver, IRuntimeHintProvider, ITestCollector, ITestFilterReceiver {
+ IAbiReceiver, IRuntimeHintProvider, ITestCollector, ITestFilterReceiver,
+ IStrictShardableTest {
@Option(name = "module")
String mModule;
@@ -74,6 +76,14 @@
return mShards;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IRemoteTest getTestShard(int shardCount, int shardIndex) {
+ return new ShardableTestStub();
+ }
+
@Override
public void setAbi(IAbi abi) {
// Do nothing
@@ -108,5 +118,4 @@
public void addAllExcludeFilters(Set<String> filters) {
}
-
}
diff --git a/common/host-side/util/src/com/android/compatibility/common/util/ResultHandler.java b/common/host-side/util/src/com/android/compatibility/common/util/ResultHandler.java
index 46fa9db..d8335f4 100644
--- a/common/host-side/util/src/com/android/compatibility/common/util/ResultHandler.java
+++ b/common/host-side/util/src/com/android/compatibility/common/util/ResultHandler.java
@@ -180,7 +180,7 @@
int notExecuted =
Integer.parseInt(parser.getAttributeValue(NS, NOT_EXECUTED_ATTR));
module.setNotExecuted(notExecuted);
- int runtime = Integer.parseInt(parser.getAttributeValue(NS, RUNTIME_ATTR));
+ long runtime = Long.parseLong(parser.getAttributeValue(NS, RUNTIME_ATTR));
module.addRuntime(runtime);
while (parser.nextTag() == XmlPullParser.START_TAG) {
parser.require(XmlPullParser.START_TAG, NS, CASE_TAG);
diff --git a/common/util/Android.mk b/common/util/Android.mk
index c95508b..faf4596 100644
--- a/common/util/Android.mk
+++ b/common/util/Android.mk
@@ -42,7 +42,7 @@
LOCAL_MODULE := compatibility-common-util-hostsidelib
-LOCAL_STATIC_JAVA_LIBRARIES := junit kxml2-2.3.0 platform-test-annotations-host
+LOCAL_STATIC_JAVA_LIBRARIES := junit-host kxml2-2.3.0 platform-test-annotations-host
include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/common/util/tests/Android.mk b/common/util/tests/Android.mk
index b99d47d..5e3370b 100644
--- a/common/util/tests/Android.mk
+++ b/common/util/tests/Android.mk
@@ -18,7 +18,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := junit kxml2-2.3.0 tradefed compatibility-common-util-hostsidelib
+LOCAL_JAVA_LIBRARIES := junit-host kxml2-2.3.0 tradefed compatibility-common-util-hostsidelib
LOCAL_MODULE := compatibility-common-util-tests
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
new file mode 100644
index 0000000..69ff55e
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/BaseAppSecurityTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.appsecurity.cts;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.ddmlib.testrunner.TestResult;
+import com.android.ddmlib.testrunner.TestRunResult;
+import com.android.ddmlib.testrunner.TestResult.TestStatus;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IBuildReceiver;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+/**
+ * Base class.
+ */
+public class BaseAppSecurityTest extends DeviceTestCase implements IBuildReceiver {
+ protected static final int USER_SYSTEM = 0; // From the UserHandle class.
+
+ private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
+
+ protected IBuildInfo mBuildInfo;
+
+ /** Whether multi-user is supported. */
+ protected boolean mSupportsMultiUser;
+ protected boolean mIsSplitSystemUser;
+ protected int mPrimaryUserId;
+ /** Users we shouldn't delete in the tests */
+ private ArrayList<Integer> mFixedUsers;
+
+ @Override
+ public void setBuild(IBuildInfo buildInfo) {
+ mBuildInfo = buildInfo;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ assertNotNull(mBuildInfo); // ensure build has been set before test is run.
+
+ mSupportsMultiUser = getDevice().getMaxNumberOfUsersSupported() > 1;
+ mIsSplitSystemUser = checkIfSplitSystemUser();
+ mPrimaryUserId = getDevice().getPrimaryUserId();
+ mFixedUsers = new ArrayList();
+ mFixedUsers.add(mPrimaryUserId);
+ if (mPrimaryUserId != USER_SYSTEM) {
+ mFixedUsers.add(USER_SYSTEM);
+ }
+ getDevice().switchUser(mPrimaryUserId);
+ removeTestUsers();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ removeTestUsers();
+ super.tearDown();
+ }
+
+ /**
+ * @return the userid of the created user
+ */
+ protected int createUser() throws DeviceNotAvailableException, IllegalStateException {
+ final String command = "pm create-user "
+ + "TestUser_" + System.currentTimeMillis();
+ CLog.d("Starting command: " + command);
+ final String output = getDevice().executeShellCommand(command);
+ CLog.d("Output for command " + command + ": " + output);
+
+ if (output.startsWith("Success")) {
+ try {
+ return Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim());
+ } catch (NumberFormatException e) {
+ CLog.e("Failed to parse result: %s", output);
+ }
+ } else {
+ CLog.e("Failed to create user: %s", output);
+ }
+ throw new IllegalStateException();
+ }
+
+ private void removeTestUsers() throws Exception {
+ for (int userId : getDevice().listUsers()) {
+ if (!mFixedUsers.contains(userId)) {
+ getDevice().removeUser(userId);
+ }
+ }
+ }
+
+ private boolean checkIfSplitSystemUser() throws DeviceNotAvailableException {
+ final String commandOuput = getDevice().executeShellCommand(
+ "getprop ro.fw.system_user_split");
+ return "y".equals(commandOuput) || "yes".equals(commandOuput)
+ || "1".equals(commandOuput) || "true".equals(commandOuput)
+ || "on".equals(commandOuput);
+ }
+
+ protected void installTestAppForUser(String apk, int userId) throws Exception {
+ if (userId < 0) {
+ userId = mPrimaryUserId;
+ }
+ CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mBuildInfo);
+ assertNull(getDevice().installPackageForUser(
+ buildHelper.getTestFile(apk), true, false, userId, "-t"));
+ }
+
+ protected boolean isAppVisibleForUser(String packageName, int userId,
+ boolean matchUninstalled) throws DeviceNotAvailableException {
+ String command = "cmd package list packages --user " + userId;
+ if (matchUninstalled) command += " -u";
+ String output = getDevice().executeShellCommand(command);
+ return output.contains(packageName);
+ }
+
+ private void printTestResult(TestRunResult runResult) {
+ for (Map.Entry<TestIdentifier, TestResult> testEntry :
+ runResult.getTestResults().entrySet()) {
+ TestResult testResult = testEntry.getValue();
+ CLog.d("Test " + testEntry.getKey() + ": " + testResult.getStatus());
+ if (testResult.getStatus() != TestStatus.PASSED) {
+ CLog.d(testResult.getStackTrace());
+ }
+ }
+ }
+
+ protected boolean runDeviceTestsAsUser(String packageName,
+ String testClassName, String testMethodName, int userId) throws Exception {
+ if (testClassName != null && testClassName.startsWith(".")) {
+ testClassName = packageName + testClassName;
+ }
+
+ RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(
+ packageName, RUNNER, getDevice().getIDevice());
+ if (testClassName != null && testMethodName != null) {
+ testRunner.setMethodName(testClassName, testMethodName);
+ } else if (testClassName != null) {
+ testRunner.setClassName(testClassName);
+ }
+
+ CollectingTestListener listener = new CollectingTestListener();
+ assertTrue(getDevice().runInstrumentationTestsAsUser(testRunner, userId, listener));
+
+ TestRunResult runResult = listener.getCurrentRunResults();
+ printTestResult(runResult);
+ return !runResult.hasFailedTests() && runResult.getNumTestsInState(TestStatus.PASSED) > 0;
+ }
+}
\ No newline at end of file
diff --git a/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
new file mode 100644
index 0000000..115ebf4
--- /dev/null
+++ b/hostsidetests/appsecurity/src/android/appsecurity/cts/PackageVisibilityTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.appsecurity.cts;
+
+import com.android.tradefed.device.DeviceNotAvailableException;
+
+/**
+ * Tests for visibility of packages installed in one user, in a different user.
+ */
+public class PackageVisibilityTest extends BaseAppSecurityTest {
+
+ private static final String TINY_APK = "CtsPkgInstallTinyApp.apk";
+ private static final String TINY_PKG = "android.appsecurity.cts.tinyapp";
+
+ private static final String TEST_APK = "CtsPkgAccessApp.apk";
+ private static final String TEST_PKG = "com.android.cts.packageaccessapp";
+
+ private static final boolean MATCH_UNINSTALLED = true;
+ private static final boolean MATCH_NORMAL = false;
+
+ private String mOldVerifierValue;
+
+ public void setUp() throws Exception {
+ super.setUp();
+ mOldVerifierValue =
+ getDevice().executeShellCommand("settings get global package_verifier_enable");
+ getDevice().executeShellCommand("settings put global package_verifier_enable 0");
+ installTestAppForUser(TEST_APK, mPrimaryUserId);
+ }
+
+ public void tearDown() throws Exception {
+ getDevice().uninstallPackage(TEST_PKG);
+ getDevice().executeShellCommand("settings put global package_verifier_enable "
+ + mOldVerifierValue);
+ super.tearDown();
+ }
+
+ public void testUninstalledPackageVisibility() throws Exception {
+ if (!mSupportsMultiUser) {
+ return;
+ }
+
+ int userId = createUser();
+ assertTrue(userId > 0);
+ getDevice().startUser(userId);
+ installTestAppForUser(TEST_APK, userId);
+ installTestAppForUser(TEST_APK, mPrimaryUserId);
+
+ installTestAppForUser(TINY_APK, mPrimaryUserId);
+
+ // It is visible for the installed user, using shell commands
+ assertTrue(isAppVisibleForUser(TINY_PKG, mPrimaryUserId, MATCH_NORMAL));
+ assertTrue(isAppVisibleForUser(TINY_PKG, mPrimaryUserId, MATCH_UNINSTALLED));
+
+ // Try the same from an app
+ assertTrue(runDeviceTestsAsUser(TEST_PKG,
+ ".PackageAccessTest", "testPackageAccess_inUser", mPrimaryUserId));
+ assertTrue(runDeviceTestsAsUser(TEST_PKG,
+ ".PackageAccessTest", "testPackageAccess_inUserUninstalled", mPrimaryUserId));
+
+ // It is not visible for the other user using shell commands
+ assertFalse(isAppVisibleForUser(TINY_PKG, userId, MATCH_NORMAL));
+ assertFalse(isAppVisibleForUser(TINY_PKG, userId, MATCH_UNINSTALLED));
+
+ // Try the same from an app
+ assertTrue(runDeviceTestsAsUser(TEST_PKG,
+ ".PackageAccessTest", "testPackageAccess_notInOtherUser", userId));
+ assertTrue(runDeviceTestsAsUser(TEST_PKG,
+ ".PackageAccessTest", "testPackageAccess_notInOtherUserUninstalled", userId));
+
+ assertTrue(runDeviceTestsAsUser(TEST_PKG,
+ ".PackageAccessTest", "testPackageAccess_getPackagesCantSeeTiny", userId));
+
+ getDevice().uninstallPackage(TINY_PKG);
+
+ // Install for the new user
+ installTestAppForUser(TINY_APK, userId);
+
+ // It is visible for the installed user
+ assertTrue(isAppVisibleForUser(TINY_PKG, userId, MATCH_NORMAL));
+ assertTrue(isAppVisibleForUser(TINY_PKG, userId, MATCH_UNINSTALLED));
+
+ // It is not visible for the other user
+ assertFalse(isAppVisibleForUser(TINY_PKG, mPrimaryUserId, MATCH_NORMAL));
+ assertFalse(isAppVisibleForUser(TINY_PKG, mPrimaryUserId, MATCH_UNINSTALLED));
+
+ // Uninstall with keep data
+ uninstallWithKeepDataForUser(TINY_PKG, userId);
+
+ // It is visible for the installed user, but only if match uninstalled
+ assertFalse(isAppVisibleForUser(TINY_PKG, userId, MATCH_NORMAL));
+ assertTrue(isAppVisibleForUser(TINY_PKG, userId, MATCH_UNINSTALLED));
+
+ assertTrue(runDeviceTestsAsUser(TEST_PKG,
+ ".PackageAccessTest", "testPackageAccess_getPackagesCanSeeTiny", userId));
+
+ assertTrue(runDeviceTestsAsUser(TEST_PKG,
+ ".PackageAccessTest", "testPackageAccess_notInOtherUserUninstalled",
+ mPrimaryUserId));
+ assertTrue(runDeviceTestsAsUser(TEST_PKG,
+ ".PackageAccessTest", "testPackageAccess_getPackagesCantSeeTiny", mPrimaryUserId));
+
+ getDevice().uninstallPackage(TINY_PKG);
+ getDevice().uninstallPackage(TEST_PKG);
+ }
+
+ protected void uninstallWithKeepDataForUser(String packageName, int userId)
+ throws DeviceNotAvailableException {
+ final String command = "pm uninstall -k --user " + userId + " " + packageName;
+ getDevice().executeShellCommand(command);
+ }
+}
diff --git a/hostsidetests/appsecurity/test-apps/PackageAccessApp/Android.mk b/hostsidetests/appsecurity/test-apps/PackageAccessApp/Android.mk
new file mode 100644
index 0000000..d038a70
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PackageAccessApp/Android.mk
@@ -0,0 +1,37 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ android-support-test \
+ ub-uiautomator
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsPkgAccessApp
+
+LOCAL_SDK_VERSION := test_current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/PackageAccessApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/PackageAccessApp/AndroidManifest.xml
new file mode 100644
index 0000000..8558b73
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PackageAccessApp/AndroidManifest.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.cts.packageaccessapp">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.cts.packageaccessapp"
+ android:label="Test to check package visibility."/>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/PackageAccessApp/src/com/android/cts/packageaccessapp/PackageAccessTest.java b/hostsidetests/appsecurity/test-apps/PackageAccessApp/src/com/android/cts/packageaccessapp/PackageAccessTest.java
new file mode 100644
index 0000000..ad64806
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/PackageAccessApp/src/com/android/cts/packageaccessapp/PackageAccessTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.packageaccessapp;
+
+import static junit.framework.Assert.assertFalse;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.uiautomator.UiDevice;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.internal.runners.statements.Fail;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public class PackageAccessTest {
+
+ private String TINY_PKG = "android.appsecurity.cts.tinyapp";
+
+ private UiDevice mUiDevice;
+
+ @Before
+ public void setUp() throws Exception {
+ mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ }
+
+ @Test
+ public void testPackageAccess_inUser() throws Exception {
+ PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+ try {
+ PackageInfo pi = pm.getPackageInfo(TINY_PKG, 0);
+ assertNotNull(pi);
+ } catch (NameNotFoundException e) {
+ fail("Package must be found");
+ }
+ }
+
+ @Test
+ public void testPackageAccess_inUserUninstalled() throws Exception {
+ PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+ try {
+ PackageInfo pi = pm.getPackageInfo(TINY_PKG, PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ assertNotNull(pi);
+ } catch (NameNotFoundException e) {
+ fail("Package must be found");
+ }
+ }
+
+ @Test
+ public void testPackageAccess_notInOtherUser() throws Exception {
+ PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+ try {
+ PackageInfo pi = pm.getPackageInfo(TINY_PKG, 0);
+ // If it doesn't throw an exception, then at least it should be null
+ assertNull(pi);
+ } catch (NameNotFoundException e) {
+ }
+ }
+
+ @Test
+ public void testPackageAccess_notInOtherUserUninstalled() throws Exception {
+ PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+ try {
+ PackageInfo pi = pm.getPackageInfo(TINY_PKG, PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ // If it doesn't throw an exception, then at least it should be null
+ assertNull(pi);
+ } catch (NameNotFoundException e) {
+ }
+ }
+
+ @Test
+ public void testPackageAccess_getPackagesCantSeeTiny() throws Exception {
+ PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+ List<PackageInfo> packages = pm.getInstalledPackages(
+ PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ for (PackageInfo pi : packages) {
+ if (TINY_PKG.equals(pi.packageName)) {
+ fail(TINY_PKG + " visible in user");
+ }
+ }
+ }
+
+ @Test
+ public void testPackageAccess_getPackagesCanSeeTiny() throws Exception {
+ PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+ List<PackageInfo> packages = pm.getInstalledPackages(
+ PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ for (PackageInfo pi : packages) {
+ if (TINY_PKG.equals(pi.packageName)) {
+ return;
+ }
+ }
+ fail(TINY_PKG + " not found in getInstalledPackages()");
+ }
+}
\ No newline at end of file
diff --git a/hostsidetests/compilation/assets/primary.prof b/hostsidetests/compilation/assets/primary.prof
index dbd70c7..18792ba 100644
--- a/hostsidetests/compilation/assets/primary.prof
+++ b/hostsidetests/compilation/assets/primary.prof
Binary files differ
diff --git a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/AndroidManifest.xml
index 3924d84..b049306 100644
--- a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/AndroidManifest.xml
@@ -25,15 +25,17 @@
<uses-library android:name="android.test.runner" />
<receiver
android:name="com.android.cts.comp.AdminReceiver"
- android:exported="false"
+ android:exported="true"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/device_admin"/>
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED"/>
+ <action android:name="android.app.action.PROFILE_PROVISIONING_COMPLETE"/>
</intent-filter>
</receiver>
+ <activity android:name=".provisioning.StartProvisioningActivity"></activity>
<service android:name=".CrossUserService"
android:exported="false">
diff --git a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/AdminReceiver.java b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/AdminReceiver.java
index ad52708..62665f9 100644
--- a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/AdminReceiver.java
+++ b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/AdminReceiver.java
@@ -19,8 +19,11 @@
import android.app.admin.DeviceAdminReceiver;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
public class AdminReceiver extends DeviceAdminReceiver {
+ private static final String TAG = "AdminReceiver";
// These two apps are built with this source.
public static final String COMP_DPC_PACKAGE_NAME = "com.android.cts.comp";
public static final String COMP_DPC_2_PACKAGE_NAME = "com.android.cts.comp2";
@@ -28,4 +31,13 @@
public static ComponentName getComponentName(Context context) {
return new ComponentName(context, AdminReceiver.class);
}
+
+ @Override
+ public void onProfileProvisioningComplete(Context context, Intent intent) {
+ super.onProfileProvisioningComplete(context, intent);
+ Log.i(TAG, "onProfileProvisioningComplete");
+ // Enabled profile
+ getManager(context).setProfileName(getComponentName(context), "Corp owned Managed Profile");
+ getManager(context).setProfileEnabled(getComponentName(context));
+ }
}
diff --git a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/bindservice/BindDeviceAdminServiceCorpOwnedManagedProfileTestSuite.java b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/bindservice/BindDeviceAdminServiceCorpOwnedManagedProfileTestSuite.java
index ce9efcf..c03c42f 100644
--- a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/bindservice/BindDeviceAdminServiceCorpOwnedManagedProfileTestSuite.java
+++ b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/bindservice/BindDeviceAdminServiceCorpOwnedManagedProfileTestSuite.java
@@ -37,6 +37,7 @@
import java.util.concurrent.TimeUnit;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
@@ -72,6 +73,8 @@
}
public void execute() throws Exception {
+ checkCannotBind_implicitIntent();
+ checkCannotBind_notResolvableIntent();
checkCannotBind_exportedCrossUserService();
checkCannotBind_nonManagingPackage();
checkCannotBind_sameUser();
@@ -80,6 +83,28 @@
}
/**
+ * If the intent is implicit, expected to throw {@link IllegalArgumentException}.
+ */
+ private void checkCannotBind_implicitIntent() throws Exception {
+ try {
+ final Intent implicitIntent = new Intent(Intent.ACTION_VIEW);
+ bind(implicitIntent, EMPTY_SERVICE_CONNECTION, mTargetUserHandle);
+ fail("IllegalArgumentException should be thrown");
+ } catch (IllegalArgumentException ex) {
+ MoreAsserts.assertContainsRegex("Service intent must be explicit", ex.getMessage());
+ }
+ }
+
+ /**
+ * If the intent is not resolvable, it should return {@code {@code null}}.
+ */
+ private void checkCannotBind_notResolvableIntent() throws Exception {
+ final Intent notResolvableIntent = new Intent();
+ notResolvableIntent.setClassName(mContext, "NotExistService");
+ assertFalse(bind(notResolvableIntent, EMPTY_SERVICE_CONNECTION, mTargetUserHandle));
+ }
+
+ /**
* Make sure we cannot bind exported service.
*/
private void checkCannotBind_exportedCrossUserService() throws Exception {
@@ -88,7 +113,7 @@
bind(serviceIntent, EMPTY_SERVICE_CONNECTION, mTargetUserHandle);
fail("SecurityException should be thrown");
} catch (SecurityException ex) {
- MoreAsserts.assertContainsRegex("Invalid intent", ex.getMessage());
+ MoreAsserts.assertContainsRegex("must be unexported", ex.getMessage());
}
}
@@ -102,7 +127,7 @@
bind(serviceIntent, EMPTY_SERVICE_CONNECTION, mTargetUserHandle);
fail("SecurityException should be thrown");
} catch (SecurityException ex) {
- MoreAsserts.assertContainsRegex("Invalid intent", ex.getMessage());
+ MoreAsserts.assertContainsRegex("Only allow to bind service", ex.getMessage());
}
}
diff --git a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/provisioning/ManagedProfileProvisioningTest.java b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/provisioning/ManagedProfileProvisioningTest.java
new file mode 100644
index 0000000..7236746
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/provisioning/ManagedProfileProvisioningTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.comp.provisioning;
+
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+
+public class ManagedProfileProvisioningTest extends AndroidTestCase {
+ private static final String TAG = "ManagedProfileProvisioningTest";
+
+ public void testProvisioningCorpOwnedManagedProfile() throws Exception {
+ SilentProvisioningTestManager provisioningManager =
+ SilentProvisioningTestManager.getInstance();
+ provisioningManager.reset();
+ provisioningManager.startProvisioning(getContext());
+ Log.i(TAG, "Start provisioning");
+
+ assertTrue(provisioningManager.waitForProvisioningResult(getContext()));
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/provisioning/SilentProvisioningTestManager.java b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/provisioning/SilentProvisioningTestManager.java
new file mode 100644
index 0000000..c8b68bb
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/provisioning/SilentProvisioningTestManager.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.comp.provisioning;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+class SilentProvisioningTestManager {
+
+ private static final long TIMEOUT_SECONDS = 60;
+ private static final String TAG = "SilentProvisioningTestManager";
+
+ private static final SilentProvisioningTestManager sInstance
+ = new SilentProvisioningTestManager();
+
+ private final LinkedBlockingQueue<Boolean> mProvisioningResults = new LinkedBlockingQueue(1);
+
+ public static SilentProvisioningTestManager getInstance() {
+ return sInstance;
+ }
+
+ private SilentProvisioningTestManager() {}
+
+ public void reset() {
+ mProvisioningResults.clear();
+ }
+
+ public void startProvisioning(Context context) {
+ context.startActivity(new Intent(context, StartProvisioningActivity.class));
+ }
+
+ public void notifyProvisioningResult(boolean result) throws InterruptedException {
+ mProvisioningResults.put(result);
+ }
+
+ public boolean waitForProvisioningResult(Context context) throws InterruptedException {
+ Boolean result = mProvisioningResults.poll(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ if (result == null) {
+ Log.i(TAG, "ManagedProvisioning doesn't return result within "
+ + TIMEOUT_SECONDS + " seconds ");
+ return false;
+ }
+
+ if (!result) {
+ Log.i(TAG, "Failed to provision");
+ return false;
+ }
+
+ // Wait for profile enabled
+ ManagedProfileAddedReceiver receiver = new ManagedProfileAddedReceiver(context);
+ receiver.register();
+ return receiver.await();
+ }
+
+ private static class ManagedProfileAddedReceiver extends BroadcastReceiver {
+
+ private static final CountDownLatch mLatch = new CountDownLatch(1);
+
+ private final Context mContext;
+
+ private ManagedProfileAddedReceiver(Context context) {
+ mContext = context;
+ }
+
+ private void register() {
+ mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_MANAGED_PROFILE_ADDED));
+ }
+
+ private boolean await() throws InterruptedException {
+ return mLatch.await(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mLatch.countDown();
+ }
+ }
+}
+
+
diff --git a/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/provisioning/StartProvisioningActivity.java b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/provisioning/StartProvisioningActivity.java
new file mode 100644
index 0000000..634f5da
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CorpOwnedManagedProfile/src/com/android/cts/comp/provisioning/StartProvisioningActivity.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.comp.provisioning;
+
+import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+import com.android.cts.comp.AdminReceiver;
+
+public class StartProvisioningActivity extends Activity {
+ private static final int REQUEST_CODE = 1;
+ private static final String TAG = "StartProvisionActivity";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Reduce flakiness of the test
+ // Show activity on top of keyguard
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+ // Turn on screen to prevent activity being paused by system
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+
+ // Only provision it if the activity is not re-created
+ if (savedInstanceState == null) {
+ Intent provisioningIntent = new Intent(ACTION_PROVISION_MANAGED_PROFILE)
+ .putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+ AdminReceiver.getComponentName(this))
+ .putExtra(DevicePolicyManager.EXTRA_PROVISIONING_SKIP_ENCRYPTION, true)
+ // this flag for Corp owned only
+ .putExtra(DevicePolicyManager.EXTRA_PROVISIONING_SKIP_USER_CONSENT, true);
+
+ startActivityForResult(provisioningIntent, REQUEST_CODE);
+ Log.i(TAG, "Start provisioning intent");
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (requestCode == REQUEST_CODE) {
+ try {
+ SilentProvisioningTestManager.getInstance().notifyProvisioningResult(
+ resultCode == RESULT_OK);
+ } catch (InterruptedException e) {
+ Log.e(TAG, "notifyProvisioningResult", e);
+ }
+ } else {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java
index 8b62604..a0740fb 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/BaseUserRestrictionsTest.java
@@ -57,7 +57,8 @@
UserManager.DISALLOW_SAFE_BOOT,
UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
UserManager.DISALLOW_DATA_ROAMING,
- UserManager.DISALLOW_SET_USER_ICON
+ UserManager.DISALLOW_SET_USER_ICON,
+ UserManager.DISALLOW_BLUETOOTH
};
/**
@@ -76,6 +77,7 @@
UserManager.DISALLOW_FUN,
UserManager.DISALLOW_SAFE_BOOT,
UserManager.DISALLOW_CREATE_WINDOWS,
+ UserManager.DISALLOW_BLUETOOTH,
// UserManager.DISALLOW_DATA_ROAMING, // Not set during CTS
// PO can set them too, but when DO sets them, they're global.
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
index 1ff9b6c..5fca606 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/DeviceOwnerUserRestrictionsTest.java
@@ -51,7 +51,8 @@
UserManager.DISALLOW_SAFE_BOOT,
UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
// UserManager.DISALLOW_DATA_ROAMING, // Has unrecoverable side effects.
- UserManager.DISALLOW_SET_USER_ICON
+ UserManager.DISALLOW_SET_USER_ICON,
+ UserManager.DISALLOW_BLUETOOTH
};
public static final String[] DISALLOWED = new String[] {
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
index 8cd56bf..407e90b 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/userrestrictions/SecondaryProfileOwnerUserRestrictionsTest.java
@@ -57,7 +57,8 @@
UserManager.DISALLOW_FUN,
UserManager.DISALLOW_SAFE_BOOT,
UserManager.DISALLOW_CREATE_WINDOWS,
- UserManager.DISALLOW_DATA_ROAMING
+ UserManager.DISALLOW_DATA_ROAMING,
+ UserManager.DISALLOW_BLUETOOTH
};
@Override
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
index 197f5a7..7c8a4d5 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
@@ -26,7 +26,11 @@
LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctsdeviceutil compatibility-device-util
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctstestrunner \
+ ctsdeviceutil \
+ compatibility-device-util \
+ android-support-v4
LOCAL_SDK_VERSION := test_current
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
index 07d006c..37c46ee 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
@@ -24,6 +24,8 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
+ <uses-permission android:name="android.permission.BLUETOOTH" />
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<application
android:testOnly="true">
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/AdminActionBookkeepingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/AdminActionBookkeepingTest.java
index 06873fe..d86a27a 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/AdminActionBookkeepingTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/AdminActionBookkeepingTest.java
@@ -103,6 +103,28 @@
}
/**
+ * Test: The Device Owner should be able to set and retrieve the name of the organization
+ * managing the device.
+ */
+ public void testDeviceOwnerOrganizationName() throws Exception {
+ mDevicePolicyManager.setOrganizationName(getWho(), null);
+ assertNull(mDevicePolicyManager.getDeviceOwnerOrganizationName());
+
+ mDevicePolicyManager.setOrganizationName(getWho(), "organization");
+ assertEquals("organization", mDevicePolicyManager.getDeviceOwnerOrganizationName());
+
+ mDevicePolicyManager.setOrganizationName(getWho(), null);
+ assertNull(mDevicePolicyManager.getDeviceOwnerOrganizationName());
+ }
+
+ /**
+ * Test: When a Device Owner is set, isDeviceManaged() should return true.
+ */
+ public void testIsDeviceManaged() throws Exception {
+ assertTrue(mDevicePolicyManager.isDeviceManaged());
+ }
+
+ /**
* Helper that allows the host-side test harness to disable network logging after running the
* other tests in this file.
*/
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
index 71d8543..204b9b4 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BaseDeviceOwnerTest.java
@@ -22,6 +22,8 @@
import android.content.Intent;
import android.net.Uri;
import android.os.Process;
+import android.os.UserHandle;
+import android.support.v4.content.LocalBroadcastManager;
import android.test.AndroidTestCase;
/**
@@ -34,6 +36,10 @@
*/
public abstract class BaseDeviceOwnerTest extends AndroidTestCase {
+ final static String ACTION_USER_ADDED = "com.android.cts.deviceowner.action.USER_ADDED";
+ final static String ACTION_USER_REMOVED = "com.android.cts.deviceowner.action.USER_REMOVED";
+ final static String EXTRA_USER_HANDLE = "com.android.cts.deviceowner.extra.USER_HANDLE";
+
public static class BasicAdminReceiver extends DeviceAdminReceiver {
@Override
public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri,
@@ -43,6 +49,23 @@
}
return uri.getQueryParameter("alias");
}
+
+ @Override
+ public void onUserAdded(Context context, Intent intent, UserHandle userHandle) {
+ sendUserAddedOrRemovedBroadcast(context, ACTION_USER_ADDED, userHandle);
+ }
+
+ @Override
+ public void onUserRemoved(Context context, Intent intent, UserHandle userHandle) {
+ sendUserAddedOrRemovedBroadcast(context, ACTION_USER_REMOVED, userHandle);
+ }
+
+ private void sendUserAddedOrRemovedBroadcast(Context context, String action,
+ UserHandle userHandle) {
+ Intent intent = new Intent(action);
+ intent.putExtra(EXTRA_USER_HANDLE, userHandle);
+ LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
+ }
}
public static final String PACKAGE_NAME = BaseDeviceOwnerTest.class.getPackage().getName();
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BluetoothRestrictionTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BluetoothRestrictionTest.java
new file mode 100644
index 0000000..23ccba0
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/BluetoothRestrictionTest.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.deviceowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.bluetooth.BluetoothAdapter;
+import android.os.SystemClock;
+import android.os.UserManager;
+
+/**
+ * Test interaction between {@link UserManager#DISALLOW_BLUETOOTH} user restriction and the state
+ * of Bluetooth.
+ */
+public class BluetoothRestrictionTest extends BaseDeviceOwnerTest {
+
+ private static final int DISABLE_TIMEOUT = 8000; // ms timeout for BT disable
+ private static final int ENABLE_TIMEOUT = 10000; // ms timeout for BT enable
+ private static final int POLL_TIME = 400; // ms to poll BT state
+ private static final int CHECK_WAIT_TIME = 1000; // ms to wait before enable/disable
+
+ private BluetoothAdapter mBluetoothAdapter;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_BLUETOOTH);
+ }
+
+ public void testEnableBluetoothFailsWhenDisallowed() throws Exception {
+ if (mBluetoothAdapter == null) {
+ return;
+ }
+
+ // Make sure Bluetooth is initially disabled.
+ disable();
+
+ // Add the user restriction disallowing Bluetooth.
+ mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_BLUETOOTH);
+
+ // Check that enabling Bluetooth fails.
+ assertFalse(mBluetoothAdapter.enable());
+ }
+
+ public void testBluetoothGetsDisabledAfterRestrictionSet() throws Exception {
+ if (mBluetoothAdapter == null) {
+ return;
+ }
+
+ // Make sure Bluetooth is enabled first.
+ enable();
+
+ // Add the user restriction to disallow Bluetooth.
+ mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_BLUETOOTH);
+
+ // Check that Bluetooth gets disabled as a result.
+ assertDisabledAfterTimeout();
+ }
+
+ public void testEnableBluetoothSucceedsAfterRestrictionRemoved() throws Exception {
+ if (mBluetoothAdapter == null) {
+ return;
+ }
+
+ // Add the user restriction.
+ mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_BLUETOOTH);
+
+ // Make sure Bluetooth is disabled.
+ assertDisabledAfterTimeout();
+
+ // Remove the user restriction.
+ mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_BLUETOOTH);
+
+ // Check that it is possible to enable Bluetooth again once the restriction has been
+ // removed.
+ enable();
+ }
+
+ /** Helper to turn BT off.
+ * This method will either fail on an assert, or return with BT turned off.
+ * Behavior of getState() and isEnabled() are validated along the way.
+ */
+ private void disable() {
+ sleep(CHECK_WAIT_TIME);
+ if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) {
+ assertFalse(mBluetoothAdapter.isEnabled());
+ return;
+ }
+
+ assertEquals(BluetoothAdapter.STATE_ON, mBluetoothAdapter.getState());
+ assertTrue(mBluetoothAdapter.isEnabled());
+ mBluetoothAdapter.disable();
+ assertDisabledAfterTimeout();
+ }
+
+ /**
+ * Helper method which waits for Bluetooth to be disabled. Fails if it doesn't happen in a
+ * given time.
+ */
+ private void assertDisabledAfterTimeout() {
+ boolean turnOff = false;
+ final long timeout = SystemClock.elapsedRealtime() + DISABLE_TIMEOUT;
+ while (SystemClock.elapsedRealtime() < timeout) {
+ int state = mBluetoothAdapter.getState();
+ switch (state) {
+ case BluetoothAdapter.STATE_OFF:
+ assertFalse(mBluetoothAdapter.isEnabled());
+ return;
+ default:
+ if (state != BluetoothAdapter.STATE_ON || turnOff) {
+ assertEquals(BluetoothAdapter.STATE_TURNING_OFF, state);
+ turnOff = true;
+ }
+ break;
+ }
+ sleep(POLL_TIME);
+ }
+ fail("disable() timeout");
+ }
+
+ /** Helper to turn BT on.
+ * This method will either fail on an assert, or return with BT turned on.
+ * Behavior of getState() and isEnabled() are validated along the way.
+ */
+ private void enable() {
+ sleep(CHECK_WAIT_TIME);
+ if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
+ assertTrue(mBluetoothAdapter.isEnabled());
+ return;
+ }
+
+ assertEquals(BluetoothAdapter.STATE_OFF, mBluetoothAdapter.getState());
+ assertFalse(mBluetoothAdapter.isEnabled());
+ mBluetoothAdapter.enable();
+ assertEnabledfterTimeout();
+ }
+
+ /**
+ * Helper method which waits for Bluetooth to be enabled. Fails if it doesn't happen in a given
+ * time.
+ */
+ private void assertEnabledfterTimeout() {
+ boolean turnOn = false;
+ final long timeout = SystemClock.elapsedRealtime() + DISABLE_TIMEOUT;
+ while (SystemClock.elapsedRealtime() < timeout) {
+ int state = mBluetoothAdapter.getState();
+ switch (state) {
+ case BluetoothAdapter.STATE_ON:
+ assertTrue(mBluetoothAdapter.isEnabled());
+ return;
+ default:
+ if (state != BluetoothAdapter.STATE_OFF || turnOn) {
+ assertEquals(BluetoothAdapter.STATE_TURNING_ON, state);
+ turnOn = true;
+ }
+ break;
+ }
+ sleep(POLL_TIME);
+ }
+ fail("enable() timeout");
+ }
+
+ private static void sleep(long t) {
+ try {
+ Thread.sleep(t);
+ } catch (InterruptedException e) {}
+ }
+
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
index fe87cdb..a540c27 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
@@ -31,13 +31,17 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
-
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
import java.lang.reflect.Field;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
/**
* Test {@link DevicePolicyManager#createAndManageUser}.
*/
public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
+ private static final String TAG = "CreateAndManageUserTest";
private static final String BROADCAST_EXTRA = "broadcastExtra";
private static final String ACTION_EXTRA = "actionExtra";
@@ -274,4 +278,44 @@
// to remove a user.
assertTrue(removed);
}
+
+ public void testUserAddedOrRemovedBroadcasts() throws InterruptedException {
+ LocalBroadcastReceiver receiver = new LocalBroadcastReceiver();
+ LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(
+ getContext());
+ localBroadcastManager.registerReceiver(receiver, new IntentFilter(ACTION_USER_ADDED));
+ try {
+ mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), "Test User", getWho(),
+ null, 0);
+ assertNotNull(mUserHandle);
+ assertEquals(mUserHandle, receiver.waitForBroadcastReceived());
+ } finally {
+ localBroadcastManager.unregisterReceiver(receiver);
+ }
+ localBroadcastManager.registerReceiver(receiver, new IntentFilter(ACTION_USER_REMOVED));
+ try {
+ assertTrue(mDevicePolicyManager.removeUser(getWho(), mUserHandle));
+ assertEquals(mUserHandle, receiver.waitForBroadcastReceived());
+ mUserHandle = null;
+ } finally {
+ localBroadcastManager.unregisterReceiver(receiver);
+ }
+ }
+
+ static class LocalBroadcastReceiver extends BroadcastReceiver {
+ private SynchronousQueue<UserHandle> mQueue = new SynchronousQueue<UserHandle>();
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ UserHandle userHandle = intent.getParcelableExtra(EXTRA_USER_HANDLE);
+ Log.d(TAG, "broadcast receiver received " + intent + " with userHandle "
+ + userHandle);
+ mQueue.offer(userHandle);
+
+ }
+
+ public UserHandle waitForBroadcastReceived() throws InterruptedException {
+ return mQueue.poll(BROADCAST_TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+ }
}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
new file mode 100644
index 0000000..ea5b751
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/NetworkLoggingTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.deviceowner;
+
+import android.app.admin.NetworkEvent;
+
+import java.util.List;
+
+public class NetworkLoggingTest extends BaseDeviceOwnerTest {
+
+ private static final String MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED =
+ "There should only be one user, managed by Device Owner";
+ private static final int FAKE_BATCH_TOKEN = -666; // batch tokens are always non-negative
+
+ /**
+ * Test: setting network logging can only be done if there's one user on the device.
+ */
+ public void testSetNetworkLoggingEnabledNotPossibleIfMoreThanOneUserPresent() {
+ try {
+ mDevicePolicyManager.setNetworkLoggingEnabled(getWho(), true);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+ }
+ }
+
+ /**
+ * Test: retrieving network logs can only be done if there's one user on the device.
+ */
+ public void testRetrievingNetworkLogsNotPossibleIfMoreThanOneUserPresent() {
+ try {
+ mDevicePolicyManager.retrieveNetworkLogs(getWho(), FAKE_BATCH_TOKEN);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertEquals(e.getMessage(), MESSAGE_ONLY_ONE_MANAGED_USER_ALLOWED);
+ }
+ }
+
+ /**
+ * Test: Test enabling and disabling of network logging.
+ */
+ public void testEnablingAndDisablingNetworkLogging() {
+ mDevicePolicyManager.setNetworkLoggingEnabled(getWho(), true);
+ assertTrue(mDevicePolicyManager.isNetworkLoggingEnabled(getWho()));
+ // TODO: here test that facts about logging are shown in the UI
+ mDevicePolicyManager.setNetworkLoggingEnabled(getWho(), false);
+ assertFalse(mDevicePolicyManager.isNetworkLoggingEnabled(getWho()));
+ }
+
+ /**
+ * Test: when a wrong batch token id (not a token of the current batch) is provided, null should
+ * be returned.
+ */
+ public void testProvidingWrongBatchTokenReturnsNull() {
+ assertNull(mDevicePolicyManager.retrieveNetworkLogs(getWho(), FAKE_BATCH_TOKEN));
+ }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java
index 7e942d8..0ac50d5 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ParentProfileTest.java
@@ -74,6 +74,8 @@
.add("setKeyguardDisabledFeatures")
.add("getTrustAgentConfiguration")
.add("setTrustAgentConfiguration")
+ .add("getRequiredStrongAuthTimeout")
+ .add("setRequiredStrongAuthTimeout")
.build();
private static final String LOG_TAG = "ParentProfileTest";
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index e8bc728..a195a15 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -57,6 +57,7 @@
protected static final int FLAG_PRIMARY = 0x00000001;
protected static final int FLAG_GUEST = 0x00000004;
protected static final int FLAG_EPHEMERAL = 0x00000100;
+ protected static final int FLAG_MANAGED_PROFILE = 0x00000020;
protected static interface Settings {
public static final String GLOBAL_NAMESPACE = "global";
@@ -194,6 +195,16 @@
return getDevice().listUsers();
}
+ protected int getFirstManagedProfileUserId() throws DeviceNotAvailableException {
+ for (int userId : listUsers()) {
+ if ((getUserFlags(userId) & FLAG_MANAGED_PROFILE) != 0) {
+ return userId;
+ }
+ }
+ fail("Managed profile not found");
+ return 0;
+ }
+
protected void stopUser(int userId) throws Exception {
String stopUserCommand = "am stop-user -w -f " + userId;
CLog.d("starting command \"" + stopUserCommand + "\" and waiting.");
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusManagedProfileTest.java
index 9c4018d..45a9bab 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerPlusManagedProfileTest.java
@@ -24,6 +24,8 @@
public class DeviceOwnerPlusManagedProfileTest extends BaseDevicePolicyTest {
private static final String DEVICE_OWNER_BIND_DEVICE_ADMIN_SERVICE_TEST =
"com.android.cts.comp.DeviceOwnerBindDeviceAdminServiceTest";
+ private static final String DEVICE_OWNER_PROVISIONING_TEST =
+ "com.android.cts.comp.provisioning.ManagedProfileProvisioningTest";
private static final String MANAGED_PROFILE_BIND_DEVICE_ADMIN_SERVICE_TEST =
"com.android.cts.comp.ManagedProfileBindDeviceAdminServiceTest";
@@ -61,22 +63,20 @@
return;
}
setupManagedProfile(COMP_DPC_APK, COMP_DPC_ADMIN);
- // Installing a non managing app (neither device owner nor profile owner).
- installAppAsUser(COMP_DPC_APK2, mPrimaryUserId);
- installAppAsUser(COMP_DPC_APK2, mProfileUserId);
+ verifyBindDeviceAdminServiceAsUser();
+ }
- // Testing device owner -> profile owner.
- runDeviceTestsAsUser(
- COMP_DPC_PKG,
- DEVICE_OWNER_BIND_DEVICE_ADMIN_SERVICE_TEST,
- "testBindDeviceAdminServiceForUser_corpOwnedManagedProfile",
- mPrimaryUserId);
- // Testing profile owner -> device owner.
- runDeviceTestsAsUser(
- COMP_DPC_PKG,
- MANAGED_PROFILE_BIND_DEVICE_ADMIN_SERVICE_TEST,
- "testBindDeviceAdminServiceForUser_corpOwnedManagedProfile",
- mProfileUserId);
+ /**
+ * Same as {@link #testBindDeviceAdminServiceAsUser_corpOwnedManagedProfile} except
+ * creating managed profile through ManagedProvisioning like normal flow
+ */
+ public void testBindDeviceAdminServiceAsUser_corpOwnedManagedProfileWithManagedProvisioning()
+ throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ provisionCorpOwnedManagedProfile();
+ verifyBindDeviceAdminServiceAsUser();
}
/**
@@ -101,6 +101,25 @@
mProfileUserId);
}
+ private void verifyBindDeviceAdminServiceAsUser() throws Exception {
+ // Installing a non managing app (neither device owner nor profile owner).
+ installAppAsUser(COMP_DPC_APK2, mPrimaryUserId);
+ installAppAsUser(COMP_DPC_APK2, mProfileUserId);
+
+ // Testing device owner -> profile owner.
+ runDeviceTestsAsUser(
+ COMP_DPC_PKG,
+ DEVICE_OWNER_BIND_DEVICE_ADMIN_SERVICE_TEST,
+ "testBindDeviceAdminServiceForUser_corpOwnedManagedProfile",
+ mPrimaryUserId);
+ // Testing profile owner -> device owner.
+ runDeviceTestsAsUser(
+ COMP_DPC_PKG,
+ MANAGED_PROFILE_BIND_DEVICE_ADMIN_SERVICE_TEST,
+ "testBindDeviceAdminServiceForUser_corpOwnedManagedProfile",
+ mProfileUserId);
+ }
+
protected void setupManagedProfile(String apkName, String adminReceiverClassName)
throws Exception {
mProfileUserId = createManagedProfile(mPrimaryUserId);
@@ -108,4 +127,15 @@
setProfileOwnerOrFail(adminReceiverClassName, mProfileUserId);
startUser(mProfileUserId);
}
+
+
+ protected void provisionCorpOwnedManagedProfile()
+ throws Exception {
+ runDeviceTestsAsUser(
+ COMP_DPC_PKG,
+ DEVICE_OWNER_PROVISIONING_TEST,
+ "testProvisioningCorpOwnedManagedProfile",
+ mPrimaryUserId);
+ mProfileUserId = getFirstManagedProfileUserId();
+ }
}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index 3c31fd8..e85211f 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -279,6 +279,13 @@
}
}
+ public void testUserAddedOrRemovedBroadcasts() throws Exception {
+ if (mHasFeature && canCreateAdditionalUsers(1)) {
+ executeDeviceTestMethod(".CreateAndManageUserTest",
+ "testUserAddedOrRemovedBroadcasts");
+ }
+ }
+
public void testSecurityLoggingWithTwoUsers() throws Exception {
if (!mHasFeature || getMaxNumberOfUsersSupported() < 2) {
return;
@@ -317,6 +324,27 @@
}
}
+ public void testNetworkLoggingWithTwoUsers() throws Exception {
+ if (!mHasFeature || getMaxNumberOfUsersSupported() < 2) {
+ return;
+ }
+ int userId = -1;
+ try {
+ userId = createUser();
+ executeDeviceTestMethod(".NetworkLoggingTest",
+ "testSetNetworkLoggingEnabledNotPossibleIfMoreThanOneUserPresent");
+ executeDeviceTestMethod(".NetworkLoggingTest",
+ "testRetrievingNetworkLogsNotPossibleIfMoreThanOneUserPresent");
+ } finally {
+ removeUser(userId);
+ }
+ }
+
+ public void testNetworkLoggingWithSingleUser() throws Exception {
+ executeDeviceTestMethod(".NetworkLoggingTest", "testEnablingAndDisablingNetworkLogging");
+ executeDeviceTestMethod(".NetworkLoggingTest", "testProvidingWrongBatchTokenReturnsNull");
+ }
+
public void testLockTask() throws Exception {
if (!mHasFeature) {
return;
@@ -419,6 +447,13 @@
}
}
+ public void testBluetoothRestriction() throws Exception {
+ if (!mHasFeature) {
+ return;
+ }
+ executeDeviceOwnerTest("BluetoothRestrictionTest");
+ }
+
private void executeDeviceOwnerTest(String testClassName) throws Exception {
if (!mHasFeature) {
return;
diff --git a/hostsidetests/multiuser/src/android/host/multiuser/BaseMultiUserTest.java b/hostsidetests/multiuser/src/android/host/multiuser/BaseMultiUserTest.java
index d8232c3..ea6dadc 100644
--- a/hostsidetests/multiuser/src/android/host/multiuser/BaseMultiUserTest.java
+++ b/hostsidetests/multiuser/src/android/host/multiuser/BaseMultiUserTest.java
@@ -86,6 +86,29 @@
throw new IllegalStateException();
}
+ /**
+ * @return the userid of the created user
+ */
+ protected int createUser()
+ throws DeviceNotAvailableException, IllegalStateException {
+ final String command = "pm create-user "
+ + "TestUser_" + System.currentTimeMillis();
+ CLog.d("Starting command: " + command);
+ final String output = getDevice().executeShellCommand(command);
+ CLog.d("Output for command " + command + ": " + output);
+
+ if (output.startsWith("Success")) {
+ try {
+ return Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim());
+ } catch (NumberFormatException e) {
+ CLog.e("Failed to parse result: %s", output);
+ }
+ } else {
+ CLog.e("Failed to create user: %s", output);
+ }
+ throw new IllegalStateException();
+ }
+
private void removeTestUsers() throws Exception {
for (int userId : getDevice().listUsers()) {
if (!mFixedUsers.contains(userId)) {
diff --git a/hostsidetests/os/test-apps/HostLinkVerificationApp/Android.mk b/hostsidetests/os/test-apps/HostLinkVerificationApp/Android.mk
index 76aa570..7ab0433 100644
--- a/hostsidetests/os/test-apps/HostLinkVerificationApp/Android.mk
+++ b/hostsidetests/os/test-apps/HostLinkVerificationApp/Android.mk
@@ -21,8 +21,6 @@
LOCAL_MODULE_TAGS := tests
LOCAL_SDK_VERSION := current
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
LOCAL_PACKAGE_NAME := CtsHostLinkVerificationApp
# Tag this module as a cts test artifact
diff --git a/hostsidetests/sample/app2/Android.mk b/hostsidetests/sample/app2/Android.mk
new file mode 100644
index 0000000..0900f1f
--- /dev/null
+++ b/hostsidetests/sample/app2/Android.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Don't include this package in any target
+LOCAL_MODULE_TAGS := tests
+# When built, explicitly put it in the data partition.
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_DEX_PREOPT := false
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts
+
+LOCAL_PACKAGE_NAME := CtsSampleDeviceApp2
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/tests/core/libcore/tzdata/AndroidManifest.xml b/hostsidetests/sample/app2/AndroidManifest.xml
similarity index 62%
rename from tests/core/libcore/tzdata/AndroidManifest.xml
rename to hostsidetests/sample/app2/AndroidManifest.xml
index 8a4fad8..7d65c30 100644
--- a/tests/core/libcore/tzdata/AndroidManifest.xml
+++ b/hostsidetests/sample/app2/AndroidManifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- * Copyright (C) 2015 The Android Open Source Project
+ * Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,16 +16,14 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.tzdata">
+ package="android.sample.cts.app2">
+
<application>
<uses-library android:name="android.test.runner" />
</application>
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.sample.cts.app2" />
</manifest>
diff --git a/hostsidetests/sample/app2/src/android/sample/cts/app2/SampleDeviceTest.java b/hostsidetests/sample/app2/src/android/sample/cts/app2/SampleDeviceTest.java
new file mode 100644
index 0000000..8299d47
--- /dev/null
+++ b/hostsidetests/sample/app2/src/android/sample/cts/app2/SampleDeviceTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.sample.cts.app2;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.support.test.runner.AndroidJUnit4;
+
+/**
+ * Device-side tests for CtsSampleHostTestCases
+ */
+@RunWith(AndroidJUnit4.class)
+public class SampleDeviceTest {
+
+ @Test
+ public void testPasses() throws Exception {
+ Assert.assertTrue(true);
+ }
+
+ @Test
+ public void testAssumeFails() throws Exception {
+ Assume.assumeTrue(false);
+ }
+
+ @Test
+ public void testFails() throws Exception {
+ Assert.assertTrue(false);
+ }
+}
diff --git a/hostsidetests/sample/src/android/sample/cts/SampleHostJUnit4DeviceTest.java b/hostsidetests/sample/src/android/sample/cts/SampleHostJUnit4DeviceTest.java
new file mode 100644
index 0000000..f32c523
--- /dev/null
+++ b/hostsidetests/sample/src/android/sample/cts/SampleHostJUnit4DeviceTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.sample.cts;
+
+import com.android.compatibility.common.tradefed.testtype.CompatibilityHostTestBase;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+/**
+ * Test that collects test results from test package android.sample.cts.app2.
+ *
+ * When this test builds, it also builds a support APK containing
+ * {@link android.sample.cts.app2.SampleDeviceTest}, the results of which are
+ * collected from the hostside and reported accordingly.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class SampleHostJUnit4DeviceTest extends CompatibilityHostTestBase {
+
+ private static final String TEST_PKG = "android.sample.cts.app2";
+ private static final String TEST_CLASS = TEST_PKG + "." + "SampleDeviceTest";
+ private static final String TEST_APP = "CtsSampleDeviceApp2.apk";
+
+ private static final String TEST_PASSES = "testPasses";
+ private static final String TEST_ASSUME_FAILS = "testAssumeFails";
+ private static final String TEST_FAILS = "testFails";
+
+ @Before
+ public void setUp() throws Exception {
+ installPackage(TEST_APP);
+ }
+
+ @Test
+ public void testRunDeviceTestsPasses() throws Exception {
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_PASSES));
+ }
+
+ @Test(expected=AssertionError.class)
+ public void testRunDeviceTestsFails() throws Exception {
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_FAILS));
+ }
+
+ @Test
+ public void testRunDeviceTestsAssumeFails() throws Exception {
+ Assert.assertTrue(runDeviceTests(TEST_PKG, TEST_CLASS, TEST_ASSUME_FAILS));
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ uninstallPackage(TEST_PKG);
+ }
+
+}
diff --git a/hostsidetests/sample/src/android/sample/cts/SampleHostJUnit4Test.java b/hostsidetests/sample/src/android/sample/cts/SampleHostJUnit4Test.java
new file mode 100644
index 0000000..f8f1f3a
--- /dev/null
+++ b/hostsidetests/sample/src/android/sample/cts/SampleHostJUnit4Test.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.sample.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.IDeviceTest;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.util.Scanner;
+
+/**
+ * Test to check the APK logs to Logcat.
+ *
+ * When this test builds, it also builds {@link android.sample.app.SampleDeviceActivity} into an
+ * APK which it then installed at runtime and started. The activity simply prints a message to
+ * Logcat and then gets uninstalled.
+ *
+ * Instead of extending DeviceTestCase, this JUnit4 test extends IDeviceTest and is run with
+ * tradefed's DeviceJUnit4ClassRunner
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class SampleHostJUnit4Test implements IDeviceTest {
+
+ /**
+ * The package name of the APK.
+ */
+ private static final String PACKAGE = "android.sample.app";
+
+ /**
+ * The class name of the main activity in the APK.
+ */
+ private static final String CLASS = "SampleDeviceActivity";
+
+ /**
+ * The command to launch the main activity.
+ */
+ private static final String START_COMMAND = String.format(
+ "am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE, PACKAGE, CLASS);
+
+ /**
+ * The command to clear the main activity.
+ */
+ private static final String CLEAR_COMMAND = String.format("pm clear %s", PACKAGE);
+
+ /**
+ * The test string to look for.
+ */
+ private static final String TEST_STRING = "SampleTestString";
+
+ private ITestDevice mDevice;
+
+ @Override
+ public void setDevice(ITestDevice device) {
+ mDevice = device;
+ }
+
+ @Override
+ public ITestDevice getDevice() {
+ return mDevice;
+ }
+
+ /**
+ * Tests the string was successfully logged to Logcat from the activity.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testLogcat() throws Exception {
+ ITestDevice device = getDevice();
+ assertNotNull("Device not set", device);
+ // Clear activity
+ device.executeShellCommand(CLEAR_COMMAND);
+ // Clear logcat.
+ device.executeAdbCommand("logcat", "-c");
+ // Start the APK and wait for it to complete.
+ device.executeShellCommand(START_COMMAND);
+ // Dump logcat.
+ String logs = device.executeAdbCommand("logcat", "-v", "brief", "-d", CLASS + ":I", "*:S");
+ // Search for string.
+ String testString = "";
+ Scanner in = new Scanner(logs);
+ while (in.hasNextLine()) {
+ String line = in.nextLine();
+ if(line.startsWith("I/"+CLASS)) {
+ testString = line.split(":")[1].trim();
+ }
+ }
+ in.close();
+ // Assert the logged string matches the test string.
+ assertEquals("Incorrect test string", TEST_STRING, testString);
+ }
+}
diff --git a/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java b/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java
index f276712..389048d 100644
--- a/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java
+++ b/hostsidetests/sample/src/android/sample/cts/SampleHostTest.java
@@ -47,6 +47,11 @@
"am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE, PACKAGE, CLASS);
/**
+ * The command to clear the main activity.
+ */
+ private static final String CLEAR_COMMAND = String.format("pm clear %s", PACKAGE);
+
+ /**
* The test string to look for.
*/
private static final String TEST_STRING = "SampleTestString";
@@ -58,6 +63,8 @@
*/
public void testLogcat() throws Exception {
ITestDevice device = getDevice();
+ // Clear activity
+ device.executeShellCommand(CLEAR_COMMAND);
// Clear logcat.
device.executeAdbCommand("logcat", "-c");
// Start the APK and wait for it to complete.
diff --git a/hostsidetests/security/Android.mk b/hostsidetests/security/Android.mk
index 7943785..244379d 100644
--- a/hostsidetests/security/Android.mk
+++ b/hostsidetests/security/Android.mk
@@ -18,6 +18,8 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_JAVA_RESOURCE_DIRS := res
+
LOCAL_MODULE_TAGS := optional
# tag this module as a cts test artifact
diff --git a/hostsidetests/security/res/add-debug.apk b/hostsidetests/security/res/add-debug.apk
new file mode 100644
index 0000000..dff9cb6
--- /dev/null
+++ b/hostsidetests/security/res/add-debug.apk
Binary files differ
diff --git a/hostsidetests/security/res/crash_mod.apk b/hostsidetests/security/res/crash_mod.apk
new file mode 100644
index 0000000..4991294
--- /dev/null
+++ b/hostsidetests/security/res/crash_mod.apk
Binary files differ
diff --git a/hostsidetests/security/res/poc b/hostsidetests/security/res/poc
new file mode 100644
index 0000000..8b6f012
--- /dev/null
+++ b/hostsidetests/security/res/poc
Binary files differ
diff --git a/hostsidetests/security/res/test-case b/hostsidetests/security/res/test-case
new file mode 100644
index 0000000..bac4af1
--- /dev/null
+++ b/hostsidetests/security/res/test-case
Binary files differ
diff --git a/hostsidetests/security/src/android/security/cts/AdbUtils.java b/hostsidetests/security/src/android/security/cts/AdbUtils.java
new file mode 100644
index 0000000..a3018fa
--- /dev/null
+++ b/hostsidetests/security/src/android/security/cts/AdbUtils.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 com.android.tradefed.device.CollectingOutputReceiver;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+
+import android.platform.test.annotations.RootPermissionTest;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Scanner;
+
+public class AdbUtils {
+
+ /** Runs a commandline on the specified device
+ *
+ * @param command the command to be ran
+ * @param device device for the command to be ran on
+ * @return the console output from running the command
+ */
+ public static String runCommandLine(String command, ITestDevice device) throws Exception
+ {
+ return device.executeShellCommand(command);
+ }
+
+ /**
+ * Pushes and runs a binary to the selected device
+ *
+ * @param pathToPoc a string path to poc from the /res folder
+ * @param device device to be ran on
+ * @return the console output from the binary
+ */
+ public static String runPoc(String pathToPoc, ITestDevice device) throws Exception {
+ String fullResourceName = pathToPoc;
+ File pocFile = File.createTempFile("poc", "");
+ try {
+ pocFile = extractResource(fullResourceName, pocFile);
+ device.pushFile(pocFile, "/data/local/tmp/poc");
+ device.executeShellCommand("chmod +x /data/local/tmp/poc");
+ return device.executeShellCommand("/data/local/tmp/poc");
+ } finally {
+ pocFile.delete();
+ }
+ }
+
+ /**
+ * Pushes and installs an apk to the selected device
+ *
+ * @param pathToApk a string path to apk from the /res folder
+ * @param device device to be ran on
+ * @return the output from attempting to install the apk
+ */
+ public static String installApk(String pathToApk, ITestDevice device) throws Exception {
+
+ String fullResourceName = pathToApk;
+ File apkFile = File.createTempFile("apkFile", ".apk");
+ try {
+ apkFile = extractResource(fullResourceName, apkFile);
+ return device.installPackage(apkFile, true);
+ } finally {
+ apkFile.delete();
+ }
+ }
+
+ /**
+ * Extracts the binary data from a resource and writes it to a temp file
+ */
+ private static File extractResource(String fullResourceName, File file) throws Exception {
+ try (InputStream in = AdbUtils.class.getResourceAsStream(fullResourceName);
+ OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
+ if (in == null) {
+ throw new IllegalArgumentException("Resource not found: " + fullResourceName);
+ }
+ byte[] buf = new byte[65536];
+ int chunkSize;
+ while ((chunkSize = in.read(buf)) != -1) {
+ out.write(buf, 0, chunkSize);
+ }
+ return file;
+ }
+
+ }
+}
diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
index f304607..9fe8734 100644
--- a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
@@ -658,7 +658,7 @@
/* Devices always have healthd */
@CddTest(requirement="9.7")
public void testHealthdDomain() throws DeviceNotAvailableException {
- assertDomainOne("u:r:healthd:s0", "/sbin/healthd");
+ assertDomainOne("u:r:healthd:s0", "/system/bin/healthd");
}
/* Servicemanager is always there */
diff --git a/hostsidetests/security/src/android/security/cts/SampleRootTestCase.java b/hostsidetests/security/src/android/security/cts/SampleRootTestCase.java
new file mode 100644
index 0000000..1988721
--- /dev/null
+++ b/hostsidetests/security/src/android/security/cts/SampleRootTestCase.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 com.android.tradefed.device.CollectingOutputReceiver;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+
+import android.platform.test.annotations.RootPermissionTest;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Scanner;
+
+public class SampleRootTestCase extends SecurityTestCase {
+
+ /**
+ * Sample where we use a commandline to check for a vulnerability
+ */
+ public void testHelperCmdLine() throws Exception {
+ enableAdbRoot(getDevice());
+ String command = "cd /sys/kernel/slab; ls -l 2>/dev/null | grep ffffffc0";
+ assertEquals("Lines do not match:", "", AdbUtils.runCommandLine(command, getDevice()));
+ }
+
+ /**
+ * Sample of running a binary poc that requires root and properly attains it
+ */
+ public void testHelperPocRoot() throws Exception {
+ enableAdbRoot(getDevice());
+ AdbUtils.runPoc("/test-case", getDevice());
+ }
+
+ /**
+ * Sample of running a binary poc that requires root and does not attain it
+ */
+ public void testHelperPoc() throws Exception {
+ AdbUtils.runPoc("/test-case", getDevice());
+ }
+
+ /**
+ * Sample of running an apk
+ */
+ public void testHelperApk() throws Exception {
+ String installResult = AdbUtils.installApk("/crash_mod.apk", getDevice());
+ assertNull("failed to install apk", installResult);
+ }
+}
diff --git a/hostsidetests/security/src/android/security/cts/SecurityTestCase.java b/hostsidetests/security/src/android/security/cts/SecurityTestCase.java
new file mode 100644
index 0000000..b6599c1
--- /dev/null
+++ b/hostsidetests/security/src/android/security/cts/SecurityTestCase.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 com.android.tradefed.device.CollectingOutputReceiver;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceTestCase;
+
+import android.platform.test.annotations.RootPermissionTest;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Scanner;
+
+public class SecurityTestCase extends DeviceTestCase {
+
+ private long kernelStartTime;
+
+ /**
+ * Waits for device to be online, marks the most recent boottime of the device
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ kernelStartTime = System.currentTimeMillis()/1000 -
+ Integer.parseInt(getDevice().executeShellCommand("cut -f1 -d. /proc/uptime").trim());
+ //TODO:(badash@): Watch for other things to track.
+ // Specifically time when app framework starts
+ }
+
+ /**
+ * Takes a device and runs a root command. There is a more robust version implemented by
+ * NativeDevice, but due to some other changes it isnt trivially acessible, but I can get
+ * that implementation fairly easy if we think it is a better idea.
+ */
+ public void enableAdbRoot(ITestDevice mDevice) throws DeviceNotAvailableException {
+ boolean isUserDebug =
+ "userdebug".equals(mDevice.executeShellCommand("getprop ro.build.type").trim());
+ if (!isUserDebug) {
+ //TODO(badash@): This would Noop once cl: ag/1594311 is in
+ return;
+ }
+ mDevice.executeAdbCommand("root");
+ }
+
+ /**
+ * Makes sure the phone is online, and the ensure the current boottime is within 2 seconds
+ * (due to rounding) of the previous boottime to check if The phone has crashed.
+ */
+ @Override
+ public void tearDown() throws Exception {
+ getDevice().waitForDeviceOnline(60 * 1000);
+ assertTrue("Phone has had a hard reset",
+ (System.currentTimeMillis()/1000 -
+ Integer.parseInt(getDevice().executeShellCommand("cut -f1 -d. /proc/uptime").trim())
+ - kernelStartTime < 2));
+ //TODO(badash@): add ability to catch runtime restart
+ getDevice().executeAdbCommand("unroot");
+ }
+}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/app/AndroidManifest.xml b/hostsidetests/services/activityandwindowmanager/activitymanager/app/AndroidManifest.xml
index 886ead0..c6db7e9 100755
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/app/AndroidManifest.xml
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/app/AndroidManifest.xml
@@ -166,6 +166,9 @@
<activity android:name=".TurnScreenOnActivity"
android:exported="true"
/>
+ <activity android:name=".TurnScreenOnDismissKeyguardActivity"
+ android:exported="true"
+ />
<activity android:name=".SingleTaskActivity"
android:exported="true"
android:launchMode="singleTask"
@@ -224,6 +227,9 @@
<activity android:name=".DismissKeyguardActivity"
android:exported="true"
/>
+ <activity android:name=".DismissKeyguardMethodActivity"
+ android:exported="true"
+ />
<activity android:name=".WallpaperActivity"
android:exported="true"
android:theme="@style/WallpaperTheme"
@@ -235,6 +241,16 @@
android:exported="true"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
/>
+ <activity android:name=".PortraitOrientationActivity"
+ android:exported="true"
+ android:screenOrientation="portrait"
+ android:documentLaunchMode="always"
+ />
+ <activity android:name=".LandscapeOrientationActivity"
+ android:exported="true"
+ android:screenOrientation="landscape"
+ android:documentLaunchMode="always"
+ />
</application>
</manifest>
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/BroadcastReceiverActivity.java b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/BroadcastReceiverActivity.java
index d77f8af..6dab9dd 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/BroadcastReceiverActivity.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/BroadcastReceiverActivity.java
@@ -19,6 +19,7 @@
import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
import android.app.Activity;
+import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -64,6 +65,10 @@
if (extras.getBoolean("dismissKeyguard")) {
getWindow().addFlags(FLAG_DISMISS_KEYGUARD);
}
+ if (extras.getBoolean("dismissKeyguardMethod")) {
+ getSystemService(KeyguardManager.class).dismissKeyguard(
+ BroadcastReceiverActivity.this, new KeyguardDismissLoggerCallback(), null);
+ }
}
}
}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/DismissKeyguardMethodActivity.java b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/DismissKeyguardMethodActivity.java
new file mode 100644
index 0000000..18228e7
--- /dev/null
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/DismissKeyguardMethodActivity.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.server.cts;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.app.KeyguardManager.KeyguardDismissCallback;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+public class DismissKeyguardMethodActivity extends Activity {
+
+ private final String TAG = "DismissKeyguardMethodActivity";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getSystemService(KeyguardManager.class).dismissKeyguard(this,
+ new KeyguardDismissLoggerCallback(), null);
+ }
+}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/KeyguardDismissLoggerCallback.java b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/KeyguardDismissLoggerCallback.java
new file mode 100644
index 0000000..efc0c79
--- /dev/null
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/KeyguardDismissLoggerCallback.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.server.cts;
+
+import android.app.KeyguardManager;
+import android.app.KeyguardManager.KeyguardDismissCallback;
+import android.util.Log;
+
+public class KeyguardDismissLoggerCallback extends KeyguardDismissCallback {
+
+ private final String TAG = "KeyguardDismissLoggerCallback";
+
+ @Override
+ public void onDismissError() {
+ Log.i(TAG, "onDismissError");
+ }
+
+ @Override
+ public void onDismissSucceeded() {
+ Log.i(TAG, "onDismissSucceeded");
+ }
+
+ @Override
+ public void onDismissCancelled() {
+ Log.i(TAG, "onDismissCancelled");
+ }
+}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/LandscapeOrientationActivity.java b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/LandscapeOrientationActivity.java
new file mode 100644
index 0000000..0ab69b1
--- /dev/null
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/LandscapeOrientationActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.server.cts;
+
+import android.app.Activity;
+
+public class LandscapeOrientationActivity extends Activity {
+}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/PortraitOrientationActivity.java b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/PortraitOrientationActivity.java
new file mode 100644
index 0000000..7acb4da
--- /dev/null
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/PortraitOrientationActivity.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.server.cts;
+
+import android.app.Activity;
+
+public class PortraitOrientationActivity extends Activity {
+}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/TurnScreenOnDismissKeyguardActivity.java b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/TurnScreenOnDismissKeyguardActivity.java
new file mode 100644
index 0000000..9d262a7
--- /dev/null
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/app/src/android/server/cts/TurnScreenOnDismissKeyguardActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.server.cts;
+
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+public class TurnScreenOnDismissKeyguardActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
+ | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
+ getSystemService(KeyguardManager.class).dismissKeyguard(this,
+ new KeyguardDismissLoggerCallback(), null);
+ }
+}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerActivityVisibilityTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerActivityVisibilityTests.java
index 9c909c2..a4a6191 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerActivityVisibilityTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerActivityVisibilityTests.java
@@ -34,7 +34,7 @@
private static final String BROADCAST_RECEIVER_ACTIVITY = "BroadcastReceiverActivity";
public void testVisibleBehindHomeActivity() throws Exception {
- executeShellCommand(getAmStartCmd(VISIBLE_BEHIND_ACTIVITY));
+ launchActivity(VISIBLE_BEHIND_ACTIVITY);
mAmWmState.waitForValidState(mDevice, VISIBLE_BEHIND_ACTIVITY,
FULLSCREEN_WORKSPACE_STACK_ID);
@@ -55,8 +55,8 @@
}
public void testVisibleBehindOtherActivity_NotOverHome() throws Exception {
- executeShellCommand(getAmStartCmd(VISIBLE_BEHIND_ACTIVITY));
- executeShellCommand(getAmStartCmd(TRANSLUCENT_ACTIVITY));
+ launchActivity(VISIBLE_BEHIND_ACTIVITY);
+ launchActivity(TRANSLUCENT_ACTIVITY);
mAmWmState.computeState(mDevice,
new String[] {VISIBLE_BEHIND_ACTIVITY, TRANSLUCENT_ACTIVITY});
@@ -66,6 +66,7 @@
public void testVisibleBehindOtherActivity_OverHome() throws Exception {
executeShellCommand(getAmStartCmdOverHome(VISIBLE_BEHIND_ACTIVITY));
+ mAmWmState.waitForValidState(mDevice, VISIBLE_BEHIND_ACTIVITY);
executeShellCommand(getAmStartCmdOverHome(TRANSLUCENT_ACTIVITY));
mAmWmState.computeState(mDevice,
@@ -80,6 +81,7 @@
}
executeShellCommand(getAmStartCmdOverHome(PIP_ON_PIP_ACTIVITY));
+ mAmWmState.waitForValidState(mDevice, PIP_ON_PIP_ACTIVITY);
// NOTE: moving to pinned stack will trigger the pip-on-pip activity to launch the
// translucent activity.
executeShellCommand(AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND);
@@ -96,7 +98,7 @@
*/
public void testTranslucentActivityOnTopOfHome() throws Exception {
executeShellCommand(AM_START_HOME_ACTIVITY_COMMAND);
- executeShellCommand(getAmStartCmd(TRANSLUCENT_ACTIVITY));
+ launchActivity(TRANSLUCENT_ACTIVITY);
mAmWmState.computeState(mDevice, new String[]{TRANSLUCENT_ACTIVITY});
mAmWmState.assertFrontStack(
@@ -115,9 +117,9 @@
}
executeShellCommand(AM_START_HOME_ACTIVITY_COMMAND);
- executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
+ launchActivity(TEST_ACTIVITY_NAME);
executeShellCommand(AM_START_HOME_ACTIVITY_COMMAND);
- executeShellCommand(getAmStartCmd(TRANSLUCENT_ACTIVITY));
+ launchActivity(TRANSLUCENT_ACTIVITY);
executeShellCommand(AM_MOVE_TOP_ACTIVITY_TO_PINNED_STACK_COMMAND);
mAmWmState.computeState(mDevice, new String[]{TRANSLUCENT_ACTIVITY});
@@ -145,7 +147,7 @@
public void testTurnScreenOnActivity() throws Exception {
sleepDevice();
- executeShellCommand(getAmStartCmd(TURN_SCREEN_ON_ACTIVITY_NAME));
+ launchActivity(TURN_SCREEN_ON_ACTIVITY_NAME);
mAmWmState.computeState(mDevice, new String[] { TURN_SCREEN_ON_ACTIVITY_NAME });
mAmWmState.assertVisibility(TURN_SCREEN_ON_ACTIVITY_NAME, true);
}
@@ -153,8 +155,8 @@
public void testFinishActivityInNonFocusedStack() throws Exception {
// Launch two activities in docked stack.
launchActivityInDockStack(LAUNCHING_ACTIVITY);
- launchActivity(false /* toSide */, false /* randomData */, false /* multipleTaskFlag */,
- BROADCAST_RECEIVER_ACTIVITY);
+ launchActivityFromLaunching(false /* toSide */, false /* randomData */,
+ false /* multipleTaskFlag */, BROADCAST_RECEIVER_ACTIVITY);
mAmWmState.computeState(mDevice, new String[] { BROADCAST_RECEIVER_ACTIVITY });
mAmWmState.assertVisibility(BROADCAST_RECEIVER_ACTIVITY, true);
// Launch something to fullscreen stack to make it focused.
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerAppConfigurationTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerAppConfigurationTests.java
index ce8ac3f..8636415 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerAppConfigurationTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerAppConfigurationTests.java
@@ -26,6 +26,8 @@
public class ActivityManagerAppConfigurationTests extends ActivityManagerTestBase {
private static final String RESIZEABLE_ACTIVITY_NAME = "ResizeableActivity";
private static final String TEST_ACTIVITY_NAME = "TestActivity";
+ private static final String PORTRAIT_ACTIVITY_NAME = "PortraitOrientationActivity";
+ private static final String LANDSCAPE_ACTIVITY_NAME = "LandscapeOrientationActivity";
/**
* Tests that the WindowManager#getDefaultDisplay() and the Configuration of the Activity
@@ -87,8 +89,8 @@
// support rotation.
launchActivityToSide(false /* randomData */, false /* multipleTask */, TEST_ACTIVITY_NAME);
// Launch target activity in docked stack.
- launchActivity(false /* toSide */, false /* randomData */, false /* multipleTask */,
- RESIZEABLE_ACTIVITY_NAME);
+ launchActivityFromLaunching(false /* toSide */, false /* randomData */,
+ false /* multipleTask */, RESIZEABLE_ACTIVITY_NAME);
final ReportedSizes initialSizes = getActivityDisplaySize(RESIZEABLE_ACTIVITY_NAME,
DOCKED_STACK_ID);
@@ -190,6 +192,66 @@
}
/**
+ * Test that device handles consequent requested orientations and displays the activities.
+ */
+ public void testFullscreenAppOrientationRequests() throws Exception {
+ launchActivity(PORTRAIT_ACTIVITY_NAME);
+ mAmWmState.assertVisibility(PORTRAIT_ACTIVITY_NAME, true /* visible */);
+ assertEquals("Fullscreen app requested portrait orientation",
+ 1 /* portrait */, mAmWmState.getWmState().getLastOrientation());
+
+ launchActivity(LANDSCAPE_ACTIVITY_NAME);
+ mAmWmState.assertVisibility(LANDSCAPE_ACTIVITY_NAME, true /* visible */);
+ assertEquals("Fullscreen app requested landscape orientation",
+ 0 /* landscape */, mAmWmState.getWmState().getLastOrientation());
+
+ launchActivity(PORTRAIT_ACTIVITY_NAME);
+ mAmWmState.assertVisibility(PORTRAIT_ACTIVITY_NAME, true /* visible */);
+ assertEquals("Fullscreen app requested portrait orientation",
+ 1 /* portrait */, mAmWmState.getWmState().getLastOrientation());
+ }
+
+ /**
+ * Test that device doesn't change device orientation by app request while in multi-window.
+ */
+ public void testSplitscreenPortraitAppOrientationRequests() throws Exception {
+ requestOrientationInSplitScreen(1 /* portrait */, LANDSCAPE_ACTIVITY_NAME);
+ }
+
+ /**
+ * Test that device doesn't change device orientation by app request while in multi-window.
+ */
+ public void testSplitscreenLandscapeAppOrientationRequests() throws Exception {
+ requestOrientationInSplitScreen(0 /* landscape */, PORTRAIT_ACTIVITY_NAME);
+ }
+
+ /**
+ * Rotate the device and launch specified activity in split-screen, checking if orientation
+ * didn't change.
+ */
+ private void requestOrientationInSplitScreen(int orientation, String activity)
+ throws Exception {
+ // Set initial orientation.
+ setDeviceRotation(orientation);
+
+ // Launch activities that request orientations and check that device doesn't rotate.
+ launchActivityInDockStack(LAUNCHING_ACTIVITY);
+
+ launchActivityToSide(false /* randomData */, true /* multipleTaskFlag */, activity);
+ mAmWmState.computeState(mDevice, new String[] {activity});
+ mAmWmState.assertVisibility(activity, true /* visible */);
+ assertEquals("Split-screen apps shouldn't influence device orientation",
+ orientation, mAmWmState.getWmState().getRotation());
+
+ launchActivityFromLaunching(false /* toSide */, false /* randomData */,
+ true /* multipleTask */, activity);
+ mAmWmState.computeState(mDevice, new String[] {activity});
+ mAmWmState.assertVisibility(activity, true /* visible */);
+ assertEquals("Split-screen apps shouldn't influence device orientation",
+ orientation, mAmWmState.getWmState().getRotation());
+ }
+
+ /**
* Launches activity in docked stack, moves to fullscreen stack and back to docked stack.
* Asserts that initial and final reported sizes in docked stack are the same.
*/
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java
index 19efb7c..45630e4 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerConfigChangeTests.java
@@ -58,7 +58,7 @@
private void testRotation(
String activityName, int rotationStep, int numRelaunch, int numConfigChange)
throws Exception {
- executeShellCommand(getAmStartCmd(activityName));
+ launchActivity(activityName);
final String[] waitForActivitiesVisible = new String[] {activityName};
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
@@ -78,7 +78,7 @@
private void testChangeFontScale(
String activityName, boolean relaunch) throws Exception {
- executeShellCommand(getAmStartCmd(activityName));
+ launchActivity(activityName);
final String[] waitForActivitiesVisible = new String[] {activityName};
mAmWmState.computeState(mDevice, waitForActivitiesVisible);
mAmWmState.assertContainsStack(
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java
index 2c733d1..8bd31bc 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDisplayTests.java
@@ -37,6 +37,7 @@
private static final String TEST_ACTIVITY_NAME = "TestActivity";
private static final String VIRTUAL_DISPLAY_ACTIVITY = "VirtualDisplayActivity";
+ private static final String RESIZEABLE_ACTIVITY_NAME = "ResizeableActivity";
private static final int INVALID_DENSITY_DPI = -1;
private static final int CUSTOM_DENSITY_DPI = 222;
@@ -88,7 +89,7 @@
final DisplayState newDisplay = createVirtualDisplay(CUSTOM_DENSITY_DPI);
// Launch activity on new secondary display.
- executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME, newDisplay.mDisplayId));
+ launchActivityOnDisplay(TEST_ACTIVITY_NAME, newDisplay.mDisplayId);
mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME});
mAmWmState.assertFocusedActivity("Activity launched on secondary display must be focused",
@@ -118,14 +119,14 @@
final DisplayState newDisplay = createVirtualDisplay(CUSTOM_DENSITY_DPI);
// Launch activity on new secondary display.
- executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME, newDisplay.mDisplayId));
+ launchActivityOnDisplay(TEST_ACTIVITY_NAME, newDisplay.mDisplayId);
mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME});
mAmWmState.assertFocusedActivity("Activity launched on secondary display must be focused",
TEST_ACTIVITY_NAME);
// Launch second activity without specifying display.
- executeShellCommand(getAmStartCmd(LAUNCHING_ACTIVITY));
+ launchActivity(LAUNCHING_ACTIVITY);
mAmWmState.computeState(mDevice, new String[] {LAUNCHING_ACTIVITY});
// Check that activity is launched in focused stack on external display.
@@ -148,15 +149,15 @@
final DisplayState newDisplay = createVirtualDisplay(CUSTOM_DENSITY_DPI);
// Launch activity on new secondary display.
- executeShellCommand(getAmStartCmd(LAUNCHING_ACTIVITY, newDisplay.mDisplayId));
+ launchActivityOnDisplay(LAUNCHING_ACTIVITY, newDisplay.mDisplayId);
mAmWmState.computeState(mDevice, new String[] {LAUNCHING_ACTIVITY});
mAmWmState.assertFocusedActivity("Activity launched on secondary display must be resumed",
LAUNCHING_ACTIVITY);
// Launch second activity from app on secondary display without specifying display id.
- launchActivity(false /* toSide */, false /* randomData */, false /* multipleTask */,
- TEST_ACTIVITY_NAME);
+ launchActivityFromLaunching(false /* toSide */, false /* randomData */,
+ false /* multipleTask */, TEST_ACTIVITY_NAME);
mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME});
// Check that activity is launched in focused stack on external display.
@@ -181,7 +182,7 @@
true /* launchInSplitScreen */);
// Launch activity on secondary display from the app on primary display.
- launchActivity(false /* toSide */, false /* randomData */, false /* multipleTask*/,
+ launchActivityFromLaunching(false /* toSide */, false /* randomData */, false /* multipleTask*/,
TEST_ACTIVITY_NAME, newDisplay.mDisplayId);
// Check that activity is launched on external display.
@@ -197,6 +198,39 @@
newDisplay.mDisplayId, frontStack.mDisplayId);
}
+ /**
+ * Tests launching activities on secondary and then on primary display to see if the stack
+ * visibility is not affected.
+ */
+ public void testLaunchActivitiesAffectsVisibility() throws Exception {
+ // Start launching activity.
+ launchActivityInDockStack(LAUNCHING_ACTIVITY);
+ mAmWmState.assertVisibility(LAUNCHING_ACTIVITY, true /* visible */);
+
+ // Create new virtual display.
+ final DisplayState newDisplay = createVirtualDisplay(CUSTOM_DENSITY_DPI,
+ true /* launchInSplitScreen */);
+ mAmWmState.assertVisibility(VIRTUAL_DISPLAY_ACTIVITY, true /* visible */);
+ mAmWmState.assertVisibility(LAUNCHING_ACTIVITY, true /* visible */);
+
+ // Launch activity on new secondary display.
+ launchActivityOnDisplay(TEST_ACTIVITY_NAME, newDisplay.mDisplayId);
+ mAmWmState.waitForValidState(mDevice, TEST_ACTIVITY_NAME);
+ mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, true /* visible */);
+ mAmWmState.assertVisibility(VIRTUAL_DISPLAY_ACTIVITY, true /* visible */);
+ mAmWmState.assertVisibility(LAUNCHING_ACTIVITY, true /* visible */);
+
+ // Launch activity on primary display and check if it doesn't affect activity on secondary
+ // display.
+ launchActivityFromLaunching(false /* toSide */, false /* randomData */,
+ false /* multipleTask */, RESIZEABLE_ACTIVITY_NAME);
+ mAmWmState.waitForValidState(mDevice, RESIZEABLE_ACTIVITY_NAME,
+ FULLSCREEN_WORKSPACE_STACK_ID);
+ mAmWmState.assertVisibility(TEST_ACTIVITY_NAME, true /* visible */);
+ mAmWmState.assertVisibility(VIRTUAL_DISPLAY_ACTIVITY, true /* visible */);
+ mAmWmState.assertVisibility(RESIZEABLE_ACTIVITY_NAME, true /* visible */);
+ }
+
/** Find the display that was not originally reported in oldDisplays and added in newDisplays */
private DisplayState findNewDisplayId(ReportedDisplays oldDisplays,
ReportedDisplays newDisplays) {
@@ -229,7 +263,7 @@
launchActivityToSide(false /* randomData */, false /* multipleTaskFlag */,
VIRTUAL_DISPLAY_ACTIVITY);
} else {
- executeShellCommand(getAmStartCmd(VIRTUAL_DISPLAY_ACTIVITY));
+ launchActivity(VIRTUAL_DISPLAY_ACTIVITY);
}
mAmWmState.computeState(mDevice, new String[] {VIRTUAL_DISPLAY_ACTIVITY},
false /* compareTaskAndStackBounds */);
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
index 0cc9ace..74741d9 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerDockedStackTests.java
@@ -35,7 +35,7 @@
private static final int STACK_SIZE = 300;
public void testStackList() throws Exception {
- executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
+ launchActivity(TEST_ACTIVITY_NAME);
mAmWmState.computeState(mDevice, new String[] {TEST_ACTIVITY_NAME});
mAmWmState.assertContainsStack("Must contain home stack.", HOME_STACK_ID);
mAmWmState.assertContainsStack(
@@ -318,7 +318,7 @@
public void testActivityLifeCycleOnResizeDockedStack() throws Exception {
final String[] waitTestActivityName = new String[] {TEST_ACTIVITY_NAME};
- executeShellCommand(getAmStartCmd(TEST_ACTIVITY_NAME));
+ launchActivity(TEST_ACTIVITY_NAME);
mAmWmState.computeState(mDevice, waitTestActivityName);
final Rectangle fullScreenBounds =
mAmWmState.getWmState().getStack(FULLSCREEN_WORKSPACE_STACK_ID).getBounds();
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
index 5c01362..1faccdf 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/ActivityManagerPinnedStackTests.java
@@ -69,7 +69,7 @@
public void testNonTappablePipActivity() throws Exception {
// Launch the tap-to-finish activity at a specific place
- executeShellCommand(getAmStartCmd(LAUNCH_TAP_TO_FINISH_PIP_ACTIVITY));
+ launchActivity(LAUNCH_TAP_TO_FINISH_PIP_ACTIVITY);
mAmWmState.computeState(mDevice, new String[] {PIP_ACTIVITY},
false /* compareTaskAndStackBounds */);
mAmWmState.assertContainsStack("Must contain pinned stack.", PINNED_STACK_ID);
@@ -87,7 +87,7 @@
public void testPinnedStackDefaultBounds() throws Exception {
// Launch a PIP activity
- executeShellCommand(getAmStartCmd(PIP_ACTIVITY, EXTRA_AUTO_ENTER_PIP, "true"));
+ launchActivity(PIP_ACTIVITY, EXTRA_AUTO_ENTER_PIP, "true");
mAmWmState.computeState(mDevice, new String[] {PIP_ACTIVITY},
false /* compareTaskAndStackBounds */);
@@ -110,7 +110,7 @@
public void testPinnedStackMovementBounds() throws Exception {
// Launch a PIP activity
- executeShellCommand(getAmStartCmd(PIP_ACTIVITY, EXTRA_AUTO_ENTER_PIP, "true"));
+ launchActivity(PIP_ACTIVITY, EXTRA_AUTO_ENTER_PIP, "true");
mAmWmState.computeState(mDevice, new String[] {PIP_ACTIVITY},
false /* compareTaskAndStackBounds */);
@@ -135,7 +135,7 @@
final WindowManagerState wmState = mAmWmState.getWmState();
// Launch an activity into the pinned stack
- executeShellCommand(getAmStartCmd(LAUNCH_TAP_TO_FINISH_PIP_ACTIVITY));
+ launchActivity(LAUNCH_TAP_TO_FINISH_PIP_ACTIVITY);
// Get the display dimensions
WindowManagerState.WindowState windowState = getWindowState(PIP_ACTIVITY);
@@ -156,7 +156,7 @@
public void testPinnedStackInBoundsAfterRotation() throws Exception {
// Launch an activity into the pinned stack
- executeShellCommand(getAmStartCmd(LAUNCH_TAP_TO_FINISH_PIP_ACTIVITY));
+ launchActivity(LAUNCH_TAP_TO_FINISH_PIP_ACTIVITY);
// Ensure that the PIP stack is fully visible in each orientation
setDeviceRotation(ROTATION_0);
@@ -172,7 +172,7 @@
public void testPinnedStackOffsetForIME() throws Exception {
// Launch an activity which shows an IME
- executeShellCommand(getAmStartCmd(LAUNCH_IME_WITH_PIP_ACTIVITY));
+ launchActivity(LAUNCH_IME_WITH_PIP_ACTIVITY);
mAmWmState.computeState(mDevice, new String[] {PIP_ACTIVITY},
false /* compareTaskAndStackBounds */);
@@ -187,9 +187,9 @@
}
public void testEnterPipAspectRatio() throws Exception {
- executeShellCommand(getAmStartCmd(PIP_ACTIVITY,
+ launchActivity(PIP_ACTIVITY,
EXTRA_AUTO_ENTER_PIP, "true",
- EXTRA_ASPECT_RATIO, Float.toString(VALID_ASPECT_RATIO)));
+ EXTRA_ASPECT_RATIO, Float.toString(VALID_ASPECT_RATIO));
mAmWmState.computeState(mDevice, new String[]{PIP_ACTIVITY},
false /* compareTaskAndStackBounds */);
@@ -202,9 +202,9 @@
}
public void testResizePipAspectRatio() throws Exception {
- executeShellCommand(getAmStartCmd(PIP_ACTIVITY,
+ launchActivity(PIP_ACTIVITY,
EXTRA_AUTO_ENTER_PIP, "true",
- EXTRA_RESIZE_TO_ASPECT_RATIO, Float.toString(VALID_ASPECT_RATIO)));
+ EXTRA_RESIZE_TO_ASPECT_RATIO, Float.toString(VALID_ASPECT_RATIO));
mAmWmState.computeState(mDevice, new String[]{PIP_ACTIVITY},
false /* compareTaskAndStackBounds */);
mAmWmState.assertContainsStack("Must contain pinned stack.", PINNED_STACK_ID);
@@ -224,9 +224,9 @@
public void testEnterPipExtremeAspectRatios() throws Exception {
// Assert that we could not create a pinned stack with an extreme aspect ratio
- executeShellCommand(getAmStartCmd(PIP_ACTIVITY,
+ launchActivity(PIP_ACTIVITY,
EXTRA_AUTO_ENTER_PIP, "true",
- EXTRA_ASPECT_RATIO, Float.toString(EXTREME_ASPECT_RATIO)));
+ EXTRA_ASPECT_RATIO, Float.toString(EXTREME_ASPECT_RATIO));
mAmWmState.computeState(mDevice, new String[] {PIP_ACTIVITY},
false /* compareTaskAndStackBounds */);
mAmWmState.assertDoesNotContainStack("Must not contain pinned stack.", PINNED_STACK_ID);
@@ -235,10 +235,10 @@
public void testResizePipExtremeAspectRatios() throws Exception {
// Try to resize the a normal pinned stack to an extreme aspect ratio and ensure that
// fails (the aspect ratio remains the same)
- executeShellCommand(getAmStartCmd(PIP_ACTIVITY,
+ launchActivity(PIP_ACTIVITY,
EXTRA_AUTO_ENTER_PIP, "true",
EXTRA_ASPECT_RATIO, Float.toString(VALID_ASPECT_RATIO),
- EXTRA_RESIZE_TO_ASPECT_RATIO, Float.toString(EXTREME_ASPECT_RATIO)));
+ EXTRA_RESIZE_TO_ASPECT_RATIO, Float.toString(EXTREME_ASPECT_RATIO));
mAmWmState.computeState(mDevice, new String[] {PIP_ACTIVITY},
false /* compareTaskAndStackBounds */);
mAmWmState.assertContainsStack("Must contain pinned stack.", PINNED_STACK_ID);
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/AnimationBackgroundTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/AnimationBackgroundTests.java
index d34a5cf..1179b12 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/AnimationBackgroundTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/AnimationBackgroundTests.java
@@ -23,8 +23,9 @@
public class AnimationBackgroundTests extends ActivityManagerTestBase {
public void testAnimationBackground_duringAnimation() throws Exception {
- executeShellCommand(getAmStartCmd(LAUNCHING_ACTIVITY));
- launchActivity(false, false, false, "AnimationTestActivity");
+ launchActivity(LAUNCHING_ACTIVITY);
+ launchActivityFromLaunching(false /* toSide */, false /* randomData */,
+ false /* multipleTask */, "AnimationTestActivity");
// Make sure we are in the middle of the animation.
Thread.sleep(250);
@@ -35,8 +36,9 @@
}
public void testAnimationBackground_gone() throws Exception {
- executeShellCommand(getAmStartCmd(LAUNCHING_ACTIVITY));
- launchActivity(false, false, false, "AnimationTestActivity");
+ launchActivity(LAUNCHING_ACTIVITY);
+ launchActivityFromLaunching(false /* toSide */, false /* randomData */,
+ false /* multipleTask */, "AnimationTestActivity");
mAmWmState.computeState(mDevice, new String[] { "AnimationTestActivity "});
assertFalse("window animation background needs to be gone", mAmWmState.getWmState()
.getStack(FULLSCREEN_WORKSPACE_STACK_ID)
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardLockedTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardLockedTests.java
index 28827f4..9e23e23 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardLockedTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardLockedTests.java
@@ -47,7 +47,7 @@
gotoKeyguard();
mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
assertShowingAndNotOccluded();
- executeShellCommand(getAmStartCmd("DismissKeyguardActivity"));
+ launchActivity("DismissKeyguardActivity");
enterAndConfirmLockCredential();
mAmWmState.waitForKeyguardGone(mDevice);
assertKeyguardGone();
@@ -58,10 +58,10 @@
gotoKeyguard();
mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
assertShowingAndNotOccluded();
- executeShellCommand(getAmStartCmd("ShowWhenLockedActivity"));
+ launchActivity("ShowWhenLockedActivity");
mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedActivity" });
mAmWmState.assertVisibility("ShowWhenLockedActivity", true);
- executeShellCommand(getAmStartCmd("DismissKeyguardActivity"));
+ launchActivity("DismissKeyguardActivity");
enterAndConfirmLockCredential();
mAmWmState.waitForKeyguardGone(mDevice);
assertKeyguardGone();
@@ -73,7 +73,7 @@
gotoKeyguard();
mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
assertShowingAndNotOccluded();
- executeShellCommand(getAmStartCmd("ShowWhenLockedActivity"));
+ launchActivity("ShowWhenLockedActivity");
mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedActivity" });
mAmWmState.assertVisibility("ShowWhenLockedActivity", true);
executeShellCommand("am broadcast -a trigger_broadcast --ez dismissKeyguard true");
@@ -82,4 +82,38 @@
assertKeyguardGone();
mAmWmState.assertVisibility("ShowWhenLockedActivity", true);
}
+
+ public void testDismissKeyguardActivity_method() throws Exception {
+ if (!isHandheld()) {
+ return;
+ }
+ clearLogcat();
+ gotoKeyguard();
+ mAmWmState.computeState(mDevice, null);
+ assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+ launchActivity("DismissKeyguardMethodActivity");
+ enterAndConfirmLockCredential();
+ mAmWmState.waitForKeyguardGone(mDevice);
+ mAmWmState.computeState(mDevice, new String[] { "DismissKeyguardMethodActivity"});
+ mAmWmState.assertVisibility("DismissKeyguardMethodActivity", true);
+ assertFalse(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+ assertOnDismissSucceededInLogcat();
+ }
+
+ public void testDismissKeyguardActivity_method_cancelled() throws Exception {
+ if (!isHandheld()) {
+ return;
+ }
+ clearLogcat();
+ gotoKeyguard();
+ mAmWmState.computeState(mDevice, null);
+ assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+ launchActivity("DismissKeyguardMethodActivity");
+ pressBackButton();
+ assertOnDismissCancelledInLogcat();
+ mAmWmState.computeState(mDevice, new String[] {});
+ mAmWmState.assertVisibility("DismissKeyguardMethodActivity", false);
+ assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+ unlockDeviceWithCredential();
+ }
}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTestBase.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTestBase.java
index 0ba77e0..ca86637 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTestBase.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTestBase.java
@@ -16,6 +16,11 @@
package android.server.cts;
+import static android.server.cts.StateLogger.log;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
public class KeyguardTestBase extends ActivityManagerTestBase {
protected void assertShowingAndOccluded() {
@@ -31,4 +36,36 @@
protected void assertKeyguardGone() {
assertFalse(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
}
+
+ protected void assertOnDismissSucceededInLogcat() throws Exception {
+ assertInLogcat("KeyguardDismissLoggerCallback", "onDismissSucceeded");
+ }
+
+ protected void assertOnDismissCancelledInLogcat() throws Exception {
+ assertInLogcat("KeyguardDismissLoggerCallback", "onDismissCancelled");
+ }
+
+ protected void assertOnDismissErrorInLogcat() throws Exception {
+ assertInLogcat("KeyguardDismissLoggerCallback", "onDismissError");
+ }
+
+ private void assertInLogcat(String activityName, String entry) throws Exception {
+ final Pattern pattern = Pattern.compile("(.+)" + entry);
+ int tries = 0;
+ while (tries < 5) {
+ final String[] lines = getDeviceLogsForComponent(activityName);
+ log("Looking at logcat");
+ for (int i = lines.length - 1; i >= 0; i--) {
+ final String line = lines[i].trim();
+ log(line);
+ Matcher matcher = pattern.matcher(line);
+ if (matcher.matches()) {
+ return;
+ }
+ }
+ tries++;
+ Thread.sleep(500);
+ }
+ fail("Not in logcat: " + entry);
+ }
}
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTests.java
index b3de9fd..093639a 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTests.java
@@ -28,7 +28,7 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("TestActivity"));
+ launchActivity("TestActivity");
mAmWmState.computeState(mDevice, new String[] { "TestActivity"});
mAmWmState.assertVisibility("TestActivity", true);
gotoKeyguard();
@@ -42,7 +42,7 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("ShowWhenLockedActivity"));
+ launchActivity("ShowWhenLockedActivity");
mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedActivity"});
mAmWmState.assertVisibility("ShowWhenLockedActivity", true);
gotoKeyguard();
@@ -61,7 +61,7 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("ShowWhenLockedWithDialogActivity"));
+ launchActivity("ShowWhenLockedWithDialogActivity");
mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedWithDialogActivity"});
mAmWmState.assertVisibility("ShowWhenLockedWithDialogActivity", true);
gotoKeyguard();
@@ -81,8 +81,8 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("ShowWhenLockedActivity"));
- executeShellCommand(getAmStartCmd("ShowWhenLockedTranslucentActivity"));
+ launchActivity("ShowWhenLockedActivity");
+ launchActivity("ShowWhenLockedTranslucentActivity");
mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedActivity",
"ShowWhenLockedTranslucentActivity"});
mAmWmState.assertVisibility("ShowWhenLockedActivity", true);
@@ -103,7 +103,7 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("ShowWhenLockedTranslucentActivity"));
+ launchActivity("ShowWhenLockedTranslucentActivity");
mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedTranslucentActivity"});
mAmWmState.assertVisibility("ShowWhenLockedTranslucentActivity", true);
gotoKeyguard();
@@ -122,8 +122,8 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("TestActivity"));
- executeShellCommand(getAmStartCmd("ShowWhenLockedTranslucentActivity"));
+ launchActivity("TestActivity");
+ launchActivity("ShowWhenLockedTranslucentActivity");
mAmWmState.computeState(mDevice, new String[] { "TestActivity",
"ShowWhenLockedTranslucentActivity"});
mAmWmState.assertVisibility("TestActivity", true);
@@ -141,7 +141,7 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("ShowWhenLockedDialogActivity"));
+ launchActivity("ShowWhenLockedDialogActivity");
mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedDialogActivity"});
mAmWmState.assertVisibility("ShowWhenLockedDialogActivity", true);
gotoKeyguard();
@@ -163,13 +163,59 @@
gotoKeyguard();
mAmWmState.computeState(mDevice, null);
assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
- executeShellCommand(getAmStartCmd("DismissKeyguardActivity"));
+ launchActivity("DismissKeyguardActivity");
mAmWmState.waitForKeyguardGone(mDevice);
mAmWmState.computeState(mDevice, new String[] { "DismissKeyguardActivity"});
mAmWmState.assertVisibility("DismissKeyguardActivity", true);
assertFalse(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
}
+ public void testDismissKeyguardActivity_method() throws Exception {
+ if (!isHandheld()) {
+ return;
+ }
+ clearLogcat();
+ gotoKeyguard();
+ mAmWmState.computeState(mDevice, null);
+ assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+ launchActivity("DismissKeyguardMethodActivity");
+ mAmWmState.waitForKeyguardGone(mDevice);
+ mAmWmState.computeState(mDevice, new String[] { "DismissKeyguardMethodActivity"});
+ mAmWmState.assertVisibility("DismissKeyguardMethodActivity", true);
+ assertFalse(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+ assertOnDismissSucceededInLogcat();
+ }
+
+ public void testDismissKeyguardActivity_method_notTop() throws Exception {
+ if (!isHandheld()) {
+ return;
+ }
+ clearLogcat();
+ gotoKeyguard();
+ mAmWmState.computeState(mDevice, null);
+ assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+ launchActivity("BroadcastReceiverActivity");
+ launchActivity("TestActivity");
+ executeShellCommand("am broadcast -a trigger_broadcast --ez dismissKeyguardMethod true");
+ assertOnDismissErrorInLogcat();
+ }
+
+ public void testDismissKeyguardActivity_method_turnScreenOn() throws Exception {
+ if (!isHandheld()) {
+ return;
+ }
+ clearLogcat();
+ sleepDevice();
+ mAmWmState.computeState(mDevice, null);
+ assertTrue(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+ launchActivity("TurnScreenOnDismissKeyguardActivity");
+ mAmWmState.waitForKeyguardGone(mDevice);
+ mAmWmState.computeState(mDevice, new String[] { "TurnScreenOnDismissKeyguardActivity"});
+ mAmWmState.assertVisibility("TurnScreenOnDismissKeyguardActivity", true);
+ assertFalse(mAmWmState.getAmState().getKeyguardControllerState().keyguardShowing);
+ assertOnDismissSucceededInLogcat();
+ }
+
/**
* Tests whether a FLAG_DISMISS_KEYGUARD activity repeatedly dismissed Keyguard, i.e. whenever
* lockscreen would show it gets dismissed immediately.
@@ -178,7 +224,7 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("DismissKeyguardActivity"));
+ launchActivity("DismissKeyguardActivity");
for (int i = 0; i < 3; i++) {
gotoKeyguard();
mAmWmState.computeState(mDevice, new String[] { "DismissKeyguardActivity"});
@@ -191,7 +237,7 @@
gotoKeyguard();
mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
assertShowingAndNotOccluded();
- executeShellCommand(getAmStartCmd("ShowWhenLockedActivity"));
+ launchActivity("ShowWhenLockedActivity");
mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedActivity" });
mAmWmState.assertVisibility("ShowWhenLockedActivity", true);
executeShellCommand("am broadcast -a trigger_broadcast --ez dismissKeyguard true");
@@ -207,7 +253,7 @@
gotoKeyguard();
mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
assertShowingAndNotOccluded();
- executeShellCommand(getAmStartCmd("KeyguardLockActivity"));
+ launchActivity("KeyguardLockActivity");
mAmWmState.computeState(mDevice, new String[] { "KeyguardLockActivity" });
mAmWmState.assertVisibility("KeyguardLockActivity", true);
executeShellCommand("am broadcast -a trigger_broadcast --ez finish true");
@@ -215,6 +261,26 @@
assertShowingAndNotOccluded();
}
+ public void testUnoccludeRotationChange() throws Exception {
+ if (!isHandheld()) {
+ return;
+ }
+ gotoKeyguard();
+ mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
+ assertShowingAndNotOccluded();
+ executeShellCommand(getAmStartCmd("ShowWhenLockedActivity"));
+ mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedActivity" });
+ mAmWmState.assertVisibility("ShowWhenLockedActivity", true);
+ setDeviceRotation(1);
+ pressHomeButton();
+ mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
+ mAmWmState.waitForDisplayUnfrozen(mDevice);
+ mAmWmState.assertSanity();
+ mAmWmState.assertHomeActivityVisible(false);
+ assertShowingAndNotOccluded();
+ mAmWmState.assertVisibility("ShowWhenLockedActivity", false);
+ }
+
private void assertWallpaperShowing() {
WindowState wallpaper =
mAmWmState.getWmState().findFirstWindowWithType(WindowState.TYPE_WALLPAPER);
diff --git a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTransitionTests.java b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTransitionTests.java
index 5f782e4..4aa663a 100644
--- a/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTransitionTests.java
+++ b/hostsidetests/services/activityandwindowmanager/activitymanager/src/android/server/cts/KeyguardTransitionTests.java
@@ -32,7 +32,7 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("TestActivity"));
+ launchActivity("TestActivity");
gotoKeyguard();
unlockDevice();
mAmWmState.computeState(mDevice, new String[] { "TestActivity"} );
@@ -44,7 +44,7 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("WallpaperActivity"));
+ launchActivity("WallpaperActivity");
gotoKeyguard();
unlockDevice();
mAmWmState.computeState(mDevice, new String[] { "WallpaperActivity"} );
@@ -57,7 +57,7 @@
return;
}
gotoKeyguard();
- executeShellCommand(getAmStartCmd("ShowWhenLockedActivity"));
+ launchActivity("ShowWhenLockedActivity");
mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedActivity"} );
assertEquals("Picked wrong transition", TRANSIT_KEYGUARD_OCCLUDE,
mAmWmState.getWmState().getLastTransition());
@@ -67,9 +67,9 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("ShowWhenLockedActivity"));
+ launchActivity("ShowWhenLockedActivity");
gotoKeyguard();
- executeShellCommand(getAmStartCmd("TestActivity"));
+ launchActivity("TestActivity");
mAmWmState.waitForKeyguardShowingAndNotOccluded(mDevice);
mAmWmState.computeState(mDevice, null);
assertEquals("Picked wrong transition", TRANSIT_KEYGUARD_UNOCCLUDE,
@@ -80,9 +80,9 @@
if (!isHandheld()) {
return;
}
- executeShellCommand(getAmStartCmd("ShowWhenLockedActivity"));
+ launchActivity("ShowWhenLockedActivity");
gotoKeyguard();
- executeShellCommand(getAmStartCmd("ShowWhenLockedWithDialogActivity"));
+ launchActivity("ShowWhenLockedWithDialogActivity");
mAmWmState.computeState(mDevice, new String[] { "ShowWhenLockedWithDialogActivity" });
assertEquals("Picked wrong transition", TRANSIT_ACTIVITY_OPEN,
mAmWmState.getWmState().getLastTransition());
diff --git a/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityAndWindowManagersState.java b/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityAndWindowManagersState.java
index 19f9365..f3b85cb 100644
--- a/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityAndWindowManagersState.java
+++ b/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityAndWindowManagersState.java
@@ -36,6 +36,7 @@
import java.util.Objects;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
+import java.util.regex.Pattern;
/** Combined state of the activity manager and window manager. */
public class ActivityAndWindowManagersState extends Assert {
@@ -63,7 +64,8 @@
* @param device test device.
* @param waitForActivitiesVisible array of activity names to wait for.
*/
- public void computeState(ITestDevice device, String[] waitForActivitiesVisible) throws Exception {
+ public void computeState(ITestDevice device, String[] waitForActivitiesVisible)
+ throws Exception {
computeState(device, waitForActivitiesVisible, true);
}
@@ -124,6 +126,18 @@
}
/**
+ * Wait for the activity to appear and for valid state in AM and WM.
+ *
+ * @param device test device.
+ * @param waitForActivityVisible name of activity to wait for.
+ */
+ void waitForValidState(ITestDevice device, String waitForActivityVisible)
+ throws Exception {
+ waitForValidState(device, new String[]{waitForActivityVisible}, null /* stackIds */,
+ false /* compareTaskAndStackBounds */);
+ }
+
+ /**
* Wait for the activity to appear in proper stack and for valid state in AM and WM.
*
* @param device test device.
@@ -188,6 +202,11 @@
"***Waiting for Rotation: " + rotation);
}
+ void waitForDisplayUnfrozen(ITestDevice device) throws Exception {
+ waitForWithWmState(device, state -> !state.isDisplayFrozen(),
+ "***Waiting for Display unfrozen");
+ }
+
void waitForWithAmState(ITestDevice device, Predicate<ActivityManagerState> waitCondition,
String message) throws Exception{
waitFor(device, (amState, wmState) -> waitCondition.test(amState), message);
@@ -413,7 +432,11 @@
ActivityManagerTestBase.getActivityComponentName(activityName);
final String windowName =
ActivityManagerTestBase.getWindowName(activityName);
+ assertVisibility(activityComponentName, windowName, visible);
+ }
+ private void assertVisibility(String activityComponentName, String windowName,
+ boolean visible) {
final boolean activityVisible = mAmState.isActivityVisible(activityComponentName);
final boolean windowVisible = mWmState.isWindowVisible(windowName);
@@ -428,13 +451,13 @@
}
void assertHomeActivityVisible(boolean visible) {
- final boolean activityVisible = mAmState.isHomeActivityVisible();
+ String name = mAmState.getHomeActivityName();
+ assertNotNull(name);
+ assertVisibility(name, getWindowNameForActivityName(name), visible);
+ }
- if (visible) {
- assertTrue("Home activity must be visible.", activityVisible);
- } else {
- assertFalse("Home activity must NOT be visible.", activityVisible);
- }
+ private String getWindowNameForActivityName(String activityName) {
+ return activityName.replaceAll("(.*)\\/\\.", "$1/$1.");
}
boolean taskListsInAmAndWmAreEqual() {
diff --git a/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerState.java b/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerState.java
index aff9eba..b90ebf4 100644
--- a/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerState.java
+++ b/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerState.java
@@ -267,6 +267,14 @@
return homeActivity != null && homeActivity.visible;
}
+ String getHomeActivityName() {
+ Activity activity = getHomeActivity();
+ if (activity == null) {
+ return null;
+ }
+ return activity.name;
+ }
+
private Activity getHomeActivity() {
for (ActivityStack stack : mStacks) {
if (stack.mStackId != HOME_STACK_ID) {
diff --git a/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerTestBase.java b/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerTestBase.java
index ab3cdd7..0ab9e9e 100644
--- a/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerTestBase.java
+++ b/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/ActivityManagerTestBase.java
@@ -78,6 +78,7 @@
static final String AM_MOVE_TASK = "am stack move-task ";
private static final String INPUT_KEYEVENT_HOME = "input keyevent 3";
+ private static final String INPUT_KEYEVENT_BACK = "input keyevent 4";
private static final String LOCK_CREDENTIAL = "1234";
@@ -212,9 +213,24 @@
mDevice.executeShellCommand(command, outputReceiver);
}
- protected void launchActivity(boolean toSide, boolean randomData, boolean multipleTask,
- String targetActivityName) throws Exception {
- launchActivity(toSide, randomData, multipleTask, targetActivityName, INVALID_DISPLAY_ID);
+ protected void launchActivity(final String targetActivityName, final String... keyValuePairs)
+ throws Exception {
+ executeShellCommand(getAmStartCmd(targetActivityName, keyValuePairs));
+
+ mAmWmState.waitForValidState(mDevice, targetActivityName);
+ }
+
+ protected void launchActivityOnDisplay(String targetActivityName, int displayId)
+ throws Exception {
+ executeShellCommand(getAmStartCmd(targetActivityName, displayId));
+
+ mAmWmState.waitForValidState(mDevice, targetActivityName);
+ }
+
+ protected void launchActivityFromLaunching(boolean toSide, boolean randomData,
+ boolean multipleTask, String targetActivityName) throws Exception {
+ launchActivityFromLaunching(toSide, randomData, multipleTask, targetActivityName,
+ INVALID_DISPLAY_ID);
}
/**
@@ -229,8 +245,8 @@
* @param displayId Display id where target activity should be launched.
* @throws Exception
*/
- protected void launchActivity(boolean toSide, boolean randomData, boolean multipleTask,
- String targetActivityName, int displayId) throws Exception {
+ protected void launchActivityFromLaunching(boolean toSide, boolean randomData,
+ boolean multipleTask, String targetActivityName, int displayId) throws Exception {
StringBuilder commandBuilder = new StringBuilder(getAmStartCmd(LAUNCHING_ACTIVITY));
commandBuilder.append(" -f 0x20000000");
if (toSide) {
@@ -249,6 +265,8 @@
commandBuilder.append(" --ei display_id ").append(displayId);
}
executeShellCommand(commandBuilder.toString());
+
+ mAmWmState.waitForValidState(mDevice, targetActivityName);
}
protected void launchActivityInStack(String activityName, int stackId) throws Exception {
@@ -258,7 +276,7 @@
}
protected void launchActivityInDockStack(String activityName) throws Exception {
- executeShellCommand(getAmStartCmd(activityName));
+ launchActivity(activityName);
moveActivityToDockStack(activityName);
mAmWmState.waitForValidState(mDevice, activityName, DOCKED_STACK_ID);
@@ -267,7 +285,8 @@
protected void launchActivityToSide(boolean randomData, boolean multipleTaskFlag,
String targetActivity) throws Exception {
final String activityToLaunch = targetActivity != null ? targetActivity : "TestActivity";
- launchActivity(true /* toSide */, randomData, multipleTaskFlag, activityToLaunch);
+ launchActivityFromLaunching(true /* toSide */, randomData, multipleTaskFlag,
+ activityToLaunch);
mAmWmState.waitForValidState(mDevice, activityToLaunch, FULLSCREEN_WORKSPACE_STACK_ID);
}
@@ -304,6 +323,10 @@
executeShellCommand(INPUT_KEYEVENT_HOME);
}
+ protected void pressBackButton() throws DeviceNotAvailableException {
+ executeShellCommand(INPUT_KEYEVENT_BACK);
+ }
+
// Utility method for debugging, not used directly here, but useful, so kept around.
protected void printStacksAndTasks() throws DeviceNotAvailableException {
CollectingOutputReceiver outputReceiver = new CollectingOutputReceiver();
diff --git a/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/WindowManagerState.java b/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/WindowManagerState.java
index ba1148c..87fe69d 100644
--- a/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/WindowManagerState.java
+++ b/hostsidetests/services/activityandwindowmanager/util/src/android/server/cts/WindowManagerState.java
@@ -23,6 +23,7 @@
import com.android.tradefed.device.CollectingOutputReceiver;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.device.ITestDevice;
+import com.sun.org.apache.xpath.internal.operations.Bool;
import java.awt.*;
import java.util.ArrayList;
@@ -81,6 +82,8 @@
"movementBounds=\\[(\\d+),(\\d+)\\]\\[(\\d+),(\\d+)\\]");
private static final Pattern sRotationPattern = Pattern.compile(
"mRotation=(\\d).*");
+ private static final Pattern sLastOrientationPattern = Pattern.compile(
+ ".*mLastOrientation=(\\d)");
private static final Pattern sLastAppTransitionPattern =
Pattern.compile("mLastUsedAppTransition=(.+)");
@@ -93,6 +96,9 @@
private static final Pattern sDisplayIdPattern =
Pattern.compile("Display: mDisplayId=(\\d+)");
+ private static final Pattern sDisplayFrozenPattern =
+ Pattern.compile("mDisplayFrozen=([a-z]*) .*");
+
private static final Pattern[] sExtractStackExitPatterns = {
sStackIdPattern, sWindowPattern, sStartingWindowPattern, sExitingWindowPattern,
sDebuggerWindowPattern, sFocusedWindowPattern, sAppErrorFocusedWindowPattern,
@@ -117,6 +123,8 @@
private final Rectangle mPinnedStackMovementBounds = new Rectangle();
private final LinkedList<String> mSysDump = new LinkedList();
private int mRotation;
+ private int mLastOrientation;
+ private boolean mDisplayFrozen;
void computeState(ITestDevice device) throws DeviceNotAvailableException {
// It is possible the system is in the middle of transition to the right state when we get
@@ -307,6 +315,20 @@
mRotation = Integer.parseInt(matcher.group(1));
continue;
}
+
+ matcher = sLastOrientationPattern.matcher(line);
+ if (matcher.matches()) {
+ log(line);
+ mLastOrientation = Integer.parseInt(matcher.group(1));
+ continue;
+ }
+
+ matcher = sDisplayFrozenPattern.matcher(line);
+ if (matcher.matches()) {
+ log(line);
+ mDisplayFrozen = Boolean.parseBoolean(matcher.group(1));
+ continue;
+ }
}
}
@@ -375,6 +397,10 @@
return mRotation;
}
+ int getLastOrientation() {
+ return mLastOrientation;
+ }
+
boolean containsStack(int stackId) {
for (WindowStack stack : mStacks) {
if (stackId == stack.mStackId) {
@@ -442,6 +468,10 @@
return null;
}
+ public boolean isDisplayFrozen() {
+ return mDisplayFrozen;
+ }
+
private void reset() {
mSysDump.clear();
mStacks.clear();
diff --git a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
index b91efb7..e20871b 100644
--- a/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
+++ b/hostsidetests/webkit/app/src/com/android/cts/webkit/WebViewDeviceSideStartupTest.java
@@ -19,11 +19,13 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.cts.util.NullWebViewUtils;
+import android.os.StrictMode;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
+import android.webkit.WebView;
import android.webkit.cts.CtsTestServer;
import android.webkit.cts.WebViewOnUiThread;
import android.webkit.WebView;
@@ -144,4 +146,56 @@
assertEquals(expected.versionName, actual.versionName);
assertEquals(expected.lastUpdateTime, actual.lastUpdateTime);
}
+
+ @UiThreadTest
+ public void testStrictModeNotViolatedOnStartup() throws Throwable {
+ StrictMode.ThreadPolicy oldThreadPolicy = StrictMode.getThreadPolicy();
+ StrictMode.VmPolicy oldVmPolicy = StrictMode.getVmPolicy();
+ StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
+ .detectAll()
+ .penaltyLog()
+ .penaltyDeath()
+ .build());
+ StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
+ .detectAll()
+ .penaltyLog()
+ .penaltyDeath()
+ .build());
+
+ try {
+ createWebViewAndNavigate();
+ // Try to force Garbage Collection to catch any StrictMode violations triggered in
+ // finalizers.
+ for(int n = 0; n < 5; n++) {
+ Runtime.getRuntime().gc();
+ Thread.sleep(200);
+ }
+ } finally {
+ StrictMode.setThreadPolicy(oldThreadPolicy);
+ StrictMode.setVmPolicy(oldVmPolicy);
+ }
+ }
+
+ private void createWebViewAndNavigate() {
+ try {
+ mActivity.createAndAttachWebView();
+ } catch (Throwable t) {
+ NullWebViewUtils.determineIfWebViewAvailable(mActivity, t);
+ if (NullWebViewUtils.isWebViewAvailable()) {
+ // Rethrow t if WebView is available (because then we failed in some way that
+ // indicates that the device supports WebView but couldn't load it for some reason).
+ throw t;
+ } else {
+ // No WebView available - bail out!
+ return;
+ }
+ }
+
+ // WebView is available, so try to call some WebView APIs to ensure they don't cause
+ // strictmode violations
+
+ WebViewOnUiThread onUiThread = new WebViewOnUiThread(this, mActivity.getWebView());
+ onUiThread.loadUrlAndWaitForCompletion("about:blank");
+ onUiThread.loadUrlAndWaitForCompletion("");
+ }
}
diff --git a/hostsidetests/webkit/src/com/android/cts/webkit/WebViewHostSideStartupTest.java b/hostsidetests/webkit/src/com/android/cts/webkit/WebViewHostSideStartupTest.java
index 90f24f7..53f4a49 100644
--- a/hostsidetests/webkit/src/com/android/cts/webkit/WebViewHostSideStartupTest.java
+++ b/hostsidetests/webkit/src/com/android/cts/webkit/WebViewHostSideStartupTest.java
@@ -49,6 +49,11 @@
"testGetCurrentWebViewPackage"));
}
+ public void testStrictMode() throws DeviceNotAvailableException {
+ assertTrue(runDeviceTest(DEVICE_WEBVIEW_STARTUP_PKG, DEVICE_WEBVIEW_STARTUP_TEST_CLASS,
+ "testStrictModeNotViolatedOnStartup"));
+ }
+
private boolean runDeviceTest(String packageName, String testClassName,
String testMethodName) throws DeviceNotAvailableException {
testClassName = packageName + "." + testClassName;
@@ -64,4 +69,3 @@
return !runResult.hasFailedTests() && runResult.getNumTestsInState(TestStatus.PASSED) > 0;
}
}
-
diff --git a/libs/deviceutil/Android.mk b/libs/deviceutil/Android.mk
index b5d9b1b..51a5379 100644
--- a/libs/deviceutil/Android.mk
+++ b/libs/deviceutil/Android.mk
@@ -16,9 +16,7 @@
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := \
- $(call all-java-files-under, src) \
- $(call all-java-files-under, ../commonutil/src)
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
diff --git a/libs/deviceutil/src/android/cts/util/MediaUtils.java b/libs/deviceutil/src/android/cts/util/MediaUtils.java
index 2c6aeae..f02ba14 100644
--- a/libs/deviceutil/src/android/cts/util/MediaUtils.java
+++ b/libs/deviceutil/src/android/cts/util/MediaUtils.java
@@ -17,6 +17,8 @@
import android.content.Context;
import android.content.res.AssetFileDescriptor;
+import android.drm.DrmConvertedStatus;
+import android.drm.DrmManagerClient;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaCodecInfo.CodecCapabilities;
@@ -42,6 +44,8 @@
import static junit.framework.Assert.assertTrue;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
public class MediaUtils {
private static final String TAG = "MediaUtils";
@@ -875,6 +879,134 @@
private boolean mSorted = false;
}
+ /**
+ * Convert a forward lock .dm message stream to a .fl file
+ * @param context Context to use
+ * @param dmStream The .dm message
+ * @param flFile The output file to be written
+ * @return success
+ */
+ public static boolean convertDmToFl(
+ Context context,
+ InputStream dmStream,
+ RandomAccessFile flFile) {
+ final String MIMETYPE_DRM_MESSAGE = "application/vnd.oma.drm.message";
+ byte[] dmData = new byte[10000];
+ int totalRead = 0;
+ int numRead;
+ while (true) {
+ try {
+ numRead = dmStream.read(dmData, totalRead, dmData.length - totalRead);
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to read from input file");
+ return false;
+ }
+ if (numRead == -1) {
+ break;
+ }
+ totalRead += numRead;
+ if (totalRead == dmData.length) {
+ // grow array
+ dmData = Arrays.copyOf(dmData, dmData.length + 10000);
+ }
+ }
+ byte[] fileData = Arrays.copyOf(dmData, totalRead);
+
+ DrmManagerClient drmClient = null;
+ try {
+ drmClient = new DrmManagerClient(context);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "DrmManagerClient instance could not be created, context is Illegal.");
+ return false;
+ } catch (IllegalStateException e) {
+ Log.w(TAG, "DrmManagerClient didn't initialize properly.");
+ return false;
+ }
+
+ try {
+ int convertSessionId = -1;
+ try {
+ convertSessionId = drmClient.openConvertSession(MIMETYPE_DRM_MESSAGE);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "Conversion of Mimetype: " + MIMETYPE_DRM_MESSAGE
+ + " is not supported.", e);
+ return false;
+ } catch (IllegalStateException e) {
+ Log.w(TAG, "Could not access Open DrmFramework.", e);
+ return false;
+ }
+
+ if (convertSessionId < 0) {
+ Log.w(TAG, "Failed to open session.");
+ return false;
+ }
+
+ DrmConvertedStatus convertedStatus = null;
+ try {
+ convertedStatus = drmClient.convertData(convertSessionId, fileData);
+ } catch (IllegalArgumentException e) {
+ Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: "
+ + convertSessionId, e);
+ return false;
+ } catch (IllegalStateException e) {
+ Log.w(TAG, "Could not convert data. Convertsession: " + convertSessionId, e);
+ return false;
+ }
+
+ if (convertedStatus == null ||
+ convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK ||
+ convertedStatus.convertedData == null) {
+ Log.w(TAG, "Error in converting data. Convertsession: " + convertSessionId);
+ try {
+ DrmConvertedStatus result = drmClient.closeConvertSession(convertSessionId);
+ if (result.statusCode != DrmConvertedStatus.STATUS_OK) {
+ Log.w(TAG, "Conversion failed with status: " + result.statusCode);
+ return false;
+ }
+ } catch (IllegalStateException e) {
+ Log.w(TAG, "Could not close session. Convertsession: " +
+ convertSessionId, e);
+ }
+ return false;
+ }
+
+ try {
+ flFile.write(convertedStatus.convertedData, 0, convertedStatus.convertedData.length);
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to write to output file: " + e);
+ return false;
+ }
+
+ try {
+ convertedStatus = drmClient.closeConvertSession(convertSessionId);
+ } catch (IllegalStateException e) {
+ Log.w(TAG, "Could not close convertsession. Convertsession: " +
+ convertSessionId, e);
+ return false;
+ }
+
+ if (convertedStatus == null ||
+ convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK ||
+ convertedStatus.convertedData == null) {
+ Log.w(TAG, "Error in closing session. Convertsession: " + convertSessionId);
+ return false;
+ }
+
+ try {
+ flFile.seek(convertedStatus.offset);
+ flFile.write(convertedStatus.convertedData);
+ } catch (IOException e) {
+ Log.w(TAG, "Could not update file.", e);
+ return false;
+ }
+
+ return true;
+ } finally {
+ drmClient.close();
+ }
+ }
+
+
/*
* -------------------------------------- END --------------------------------------
*/
diff --git a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
index 1256546..4ce99ce 100644
--- a/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
+++ b/tests/accessibility/src/android/view/accessibility/cts/AccessibilityManagerTest.java
@@ -173,7 +173,7 @@
}
public void testInterrupt() throws Exception {
- // The APIs are heavily tested in the android.accessibiliyservice package.
+ // The APIs are heavily tested in the android.accessibilityservice package.
// This just makes sure the call does not throw an exception.
waitForAccessibilityEnabled();
mAccessibilityManager.interrupt();
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index ce096fe..499b366 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -30,6 +30,7 @@
import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
@@ -330,10 +331,10 @@
new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
try {
// create the notification to send
- channel.setVibration(true);
+ channel.enableVibration(true);
channel.setLights(true);
channel.setBypassDnd(true);
- notificationManager.createNotificationChannel(channel);
+ notificationManager.createNotificationChannel(channel, (createdChannel) -> {}, null);
NotificationChannel created =
notificationManager.getNotificationChannel(channel.getId());
final int notificationId = 1;
@@ -390,6 +391,37 @@
}
}
+ @MediumTest
+ public void testInterrupt_notifiesService() {
+ getInstrumentation()
+ .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES);
+ InstrumentedAccessibilityService service = InstrumentedAccessibilityService.enableService(
+ this, InstrumentedAccessibilityService.class);
+ try {
+ assertFalse(service.wasOnInterruptCalled());
+
+ getActivity().runOnUiThread(() -> {
+ AccessibilityManager accessibilityManager = (AccessibilityManager) getActivity()
+ .getSystemService(Service.ACCESSIBILITY_SERVICE);
+ accessibilityManager.interrupt();
+ });
+
+ Object waitObject = service.getInterruptWaitObject();
+ synchronized (waitObject) {
+ if (!service.wasOnInterruptCalled()) {
+ try {
+ waitObject.wait(TIMEOUT_ASYNC_PROCESSING);
+ } catch (InterruptedException e) {
+ // Do nothing
+ }
+ }
+ }
+ assertTrue(service.wasOnInterruptCalled());
+ } finally {
+ service.disableSelfAndRemove();
+ }
+ }
+
/**
* Compares all properties of the <code>first</code> and the
* <code>second</code>.
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
index 8dbbeef..31ccee1 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityGestureDispatchTest.java
@@ -14,12 +14,23 @@
package android.accessibilityservice.cts;
+import static android.accessibilityservice.GestureDescription.StrokeDescription.INVALID_STROKE_ID;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.any;
+import static org.hamcrest.CoreMatchers.both;
+import static org.hamcrest.CoreMatchers.everyItem;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.MatcherAssert.assertThat;
+
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.GestureDescription;
+import android.accessibilityservice.GestureDescription.StrokeDescription;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Matrix;
import android.graphics.Path;
+import android.graphics.Point;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.SystemClock;
@@ -29,6 +40,9 @@
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.TextView;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
import java.util.ArrayList;
import java.util.List;
@@ -42,6 +56,20 @@
private static final int GESTURE_COMPLETION_TIMEOUT = 5000; // millis
private static final int MOTION_EVENT_TIMEOUT = 1000; // millis
+ private static final Matcher<MotionEvent> IS_ACTION_DOWN =
+ new MotionEventActionMatcher(MotionEvent.ACTION_DOWN);
+ private static final Matcher<MotionEvent> IS_ACTION_POINTER_DOWN =
+ new MotionEventActionMatcher(MotionEvent.ACTION_POINTER_DOWN);
+ private static final Matcher<MotionEvent> IS_ACTION_UP =
+ new MotionEventActionMatcher(MotionEvent.ACTION_UP);
+ private static final Matcher<MotionEvent> IS_ACTION_POINTER_UP =
+ new MotionEventActionMatcher(MotionEvent.ACTION_POINTER_UP);
+ private static final Matcher<MotionEvent> IS_ACTION_CANCEL =
+ new MotionEventActionMatcher(MotionEvent.ACTION_CANCEL);
+ private static final Matcher<MotionEvent> IS_ACTION_MOVE =
+ new MotionEventActionMatcher(MotionEvent.ACTION_MOVE);
+
+
final List<MotionEvent> mMotionEvents = new ArrayList<>();
StubGestureAccessibilityService mService;
MyTouchListener mMyTouchListener = new MyTouchListener();
@@ -60,7 +88,6 @@
@Override
public void setUp() throws Exception {
super.setUp();
-
PackageManager pm = getInstrumentation().getContext().getPackageManager();
mHasTouchScreen = pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
|| pm.hasSystemFeature(PackageManager.FEATURE_FAKETOUCH);
@@ -100,20 +127,19 @@
return;
}
- final int clickXInsideView = 10;
- final int clickYInsideView = 20;
- int clickX = clickXInsideView + mViewBounds.left;
- int clickY = clickYInsideView + mViewBounds.top;
- GestureDescription click = createClick(clickX, clickY);
+ Point clickPoint = new Point(10, 20);
+ GestureDescription click = createClickInViewBounds(clickPoint);
mService.runOnServiceSync(() -> mService.doDispatchGesture(click, mCallback, null));
mCallback.assertGestureCompletes(GESTURE_COMPLETION_TIMEOUT);
- waitForMotionEvents(2);
+ waitForMotionEvents(any(MotionEvent.class), 2);
assertEquals(2, mMotionEvents.size());
MotionEvent clickDown = mMotionEvents.get(0);
MotionEvent clickUp = mMotionEvents.get(1);
+ assertThat(clickDown, both(IS_ACTION_DOWN).and(isAtPoint(clickPoint)));
+ assertThat(clickUp, both(IS_ACTION_UP).and(isAtPoint(clickPoint)));
- assertEquals(MotionEvent.ACTION_DOWN, clickDown.getActionMasked());
+ // Verify other MotionEvent fields in this test to make sure they get initialized.
assertEquals(0, clickDown.getActionIndex());
assertEquals(0, clickDown.getDeviceId());
assertEquals(0, clickDown.getEdgeFlags());
@@ -121,18 +147,14 @@
assertEquals(1F, clickDown.getYPrecision());
assertEquals(1, clickDown.getPointerCount());
assertEquals(1F, clickDown.getPressure());
- assertEquals((float) clickXInsideView, clickDown.getX());
- assertEquals((float) clickYInsideView, clickDown.getY());
- assertEquals(clickDown.getDownTime(), clickDown.getEventTime());
- assertEquals(MotionEvent.ACTION_UP, clickUp.getActionMasked());
+ // Verify timing matches click
+ assertEquals(clickDown.getDownTime(), clickDown.getEventTime());
assertEquals(clickDown.getDownTime(), clickUp.getDownTime());
assertEquals(ViewConfiguration.getTapTimeout(),
clickUp.getEventTime() - clickUp.getDownTime());
assertTrue(clickDown.getEventTime() + ViewConfiguration.getLongPressTimeout()
> clickUp.getEventTime());
- assertEquals((float) clickXInsideView, clickUp.getX());
- assertEquals((float) clickYInsideView, clickUp.getY());
}
public void testLongClickAt_producesEventsWithLongClickTiming() throws InterruptedException {
@@ -140,30 +162,21 @@
return;
}
- final int clickXInsideView = 10;
- final int clickYInsideView = 20;
- int clickX = clickXInsideView + mViewBounds.left;
- int clickY = clickYInsideView + mViewBounds.top;
- GestureDescription longClick = createLongClick(clickX, clickY);
+ Point clickPoint = new Point(10, 20);
+ GestureDescription longClick = createLongClickInViewBounds(clickPoint);
mService.runOnServiceSync(() -> mService.doDispatchGesture(longClick, mCallback, null));
mCallback.assertGestureCompletes(
ViewConfiguration.getLongPressTimeout() + GESTURE_COMPLETION_TIMEOUT);
- waitForMotionEvents(2);
+ waitForMotionEvents(any(MotionEvent.class), 2);
MotionEvent clickDown = mMotionEvents.get(0);
MotionEvent clickUp = mMotionEvents.get(1);
+ assertThat(clickDown, both(IS_ACTION_DOWN).and(isAtPoint(clickPoint)));
+ assertThat(clickUp, both(IS_ACTION_UP).and(isAtPoint(clickPoint)));
- assertEquals(MotionEvent.ACTION_DOWN, clickDown.getActionMasked());
-
- assertEquals((float) clickXInsideView, clickDown.getX());
- assertEquals((float) clickYInsideView, clickDown.getY());
-
- assertEquals(MotionEvent.ACTION_UP, clickUp.getActionMasked());
assertTrue(clickDown.getEventTime() + ViewConfiguration.getLongPressTimeout()
<= clickUp.getEventTime());
assertEquals(clickDown.getDownTime(), clickUp.getDownTime());
- assertEquals((float) clickXInsideView, clickUp.getX());
- assertEquals((float) clickYInsideView, clickUp.getY());
}
public void testSwipe_shouldContainPointsInALine() throws InterruptedException {
@@ -171,45 +184,34 @@
return;
}
- int startXInsideView = 10;
- int startYInsideView = 20;
- int endXInsideView = 20;
- int endYInsideView = 40;
- int startX = startXInsideView + mViewBounds.left;
- int startY = startYInsideView + mViewBounds.top;
- int endX = endXInsideView + mViewBounds.left;
- int endY = endYInsideView + mViewBounds.top;
+ Point startPoint = new Point(10, 20);
+ Point endPoint = new Point(20, 40);
int gestureTime = 500;
- float swipeTolerance = 2.0f;
- GestureDescription swipe = createSwipe(startX, startY, endX, endY, gestureTime);
+ GestureDescription swipe = createSwipeInViewBounds(startPoint, endPoint, gestureTime);
mService.runOnServiceSync(() -> mService.doDispatchGesture(swipe, mCallback, null));
mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
- waitForUpEvent();
+ waitForMotionEvents(IS_ACTION_UP, 1);
+
int numEvents = mMotionEvents.size();
MotionEvent downEvent = mMotionEvents.get(0);
- assertEquals(MotionEvent.ACTION_DOWN, downEvent.getActionMasked());
- assertEquals(startXInsideView, (int) downEvent.getX());
- assertEquals(startYInsideView, (int) downEvent.getY());
-
MotionEvent upEvent = mMotionEvents.get(numEvents - 1);
- assertEquals(MotionEvent.ACTION_UP, upEvent.getActionMasked());
- assertEquals(endXInsideView, (int) upEvent.getX());
- assertEquals(endYInsideView, (int) upEvent.getY());
+ assertThat(downEvent, both(IS_ACTION_DOWN).and(isAtPoint(startPoint)));
+ assertThat(upEvent, both(IS_ACTION_UP).and(isAtPoint(endPoint)));
assertEquals(gestureTime, upEvent.getEventTime() - downEvent.getEventTime());
long lastEventTime = downEvent.getEventTime();
for (int i = 1; i < numEvents - 1; i++) {
MotionEvent moveEvent = mMotionEvents.get(i);
- assertEquals(MotionEvent.ACTION_MOVE, moveEvent.getActionMasked());
assertTrue(moveEvent.getEventTime() >= lastEventTime);
float fractionOfSwipe =
((float) (moveEvent.getEventTime() - downEvent.getEventTime())) / gestureTime;
- float fractionX = ((float) (endXInsideView - startXInsideView)) * fractionOfSwipe;
- float fractionY = ((float) (endYInsideView - startYInsideView)) * fractionOfSwipe;
- assertEquals(startXInsideView + fractionX, moveEvent.getX(), swipeTolerance);
- assertEquals(startYInsideView + fractionY, moveEvent.getY(), swipeTolerance);
+ float fractionX = ((float) (endPoint.x - startPoint.x)) * fractionOfSwipe + 0.5f;
+ float fractionY = ((float) (endPoint.y - startPoint.y)) * fractionOfSwipe + 0.5f;
+ Point intermediatePoint = new Point(startPoint);
+ intermediatePoint.offset((int) fractionX, (int) fractionY);
+ assertThat(moveEvent, both(IS_ACTION_MOVE).and(isAtPoint(intermediatePoint)));
lastEventTime = moveEvent.getEventTime();
}
}
@@ -219,40 +221,24 @@
return;
}
- int startXInsideView = 10;
- int startYInsideView = 20;
- int endXInsideView = 11;
- int endYInsideView = 22;
- int startX = startXInsideView + mViewBounds.left;
- int startY = startYInsideView + mViewBounds.top;
- int endX = endXInsideView + mViewBounds.left;
- int endY = endYInsideView + mViewBounds.top;
+ Point startPoint = new Point(10, 20);
+ Point intermediatePoint1 = new Point(10, 21);
+ Point intermediatePoint2 = new Point(11, 21);
+ Point intermediatePoint3 = new Point(11, 22);
+ Point endPoint = new Point(11, 22);
int gestureTime = 1000;
- GestureDescription swipe = createSwipe(startX, startY, endX, endY, gestureTime);
+ GestureDescription swipe = createSwipeInViewBounds(startPoint, endPoint, gestureTime);
mService.runOnServiceSync(() -> mService.doDispatchGesture(swipe, mCallback, null));
mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
- waitForUpEvent();
+ waitForMotionEvents(IS_ACTION_UP, 1);
assertEquals(5, mMotionEvents.size());
-
- assertEquals(MotionEvent.ACTION_DOWN, mMotionEvents.get(0).getActionMasked());
- assertEquals(MotionEvent.ACTION_MOVE, mMotionEvents.get(1).getActionMasked());
- assertEquals(MotionEvent.ACTION_MOVE, mMotionEvents.get(2).getActionMasked());
- assertEquals(MotionEvent.ACTION_MOVE, mMotionEvents.get(3).getActionMasked());
- assertEquals(MotionEvent.ACTION_UP, mMotionEvents.get(4).getActionMasked());
-
- assertEquals(startXInsideView, (int) mMotionEvents.get(0).getX());
- assertEquals(startXInsideView, (int) mMotionEvents.get(1).getX());
- assertEquals(startXInsideView + 1, (int) mMotionEvents.get(2).getX());
- assertEquals(startXInsideView + 1, (int) mMotionEvents.get(3).getX());
- assertEquals(startXInsideView + 1, (int) mMotionEvents.get(4).getX());
-
- assertEquals(startYInsideView, (int) mMotionEvents.get(0).getY());
- assertEquals(startYInsideView + 1, (int) mMotionEvents.get(1).getY());
- assertEquals(startYInsideView + 1, (int) mMotionEvents.get(2).getY());
- assertEquals(startYInsideView + 2, (int) mMotionEvents.get(3).getY());
- assertEquals(startYInsideView + 2, (int) mMotionEvents.get(4).getY());
+ assertThat(mMotionEvents.get(0), both(IS_ACTION_DOWN).and(isAtPoint(startPoint)));
+ assertThat(mMotionEvents.get(1), both(IS_ACTION_MOVE).and(isAtPoint(intermediatePoint1)));
+ assertThat(mMotionEvents.get(2), both(IS_ACTION_MOVE).and(isAtPoint(intermediatePoint2)));
+ assertThat(mMotionEvents.get(3), both(IS_ACTION_MOVE).and(isAtPoint(intermediatePoint3)));
+ assertThat(mMotionEvents.get(4), both(IS_ACTION_UP).and(isAtPoint(endPoint)));
}
public void testAngledPinch_looksReasonable() throws InterruptedException {
@@ -260,71 +246,42 @@
return;
}
- int centerXInsideView = 50;
- int centerYInsideView = 60;
- int centerX = centerXInsideView + mViewBounds.left;
- int centerY = centerYInsideView + mViewBounds.top;
+ Point centerPoint = new Point(50, 60);
int startSpacing = 100;
int endSpacing = 50;
int gestureTime = 500;
float pinchTolerance = 2.0f;
- GestureDescription pinch = createPinch(centerX, centerY, startSpacing,
+ GestureDescription pinch = createPinchInViewBounds(centerPoint, startSpacing,
endSpacing, 45.0F, gestureTime);
mService.runOnServiceSync(() -> mService.doDispatchGesture(pinch, mCallback, null));
mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
- waitForUpEvent();
+ waitForMotionEvents(IS_ACTION_UP, 1);
int numEvents = mMotionEvents.size();
- // First two events are the initial down and the pointer down
- assertEquals(MotionEvent.ACTION_DOWN, mMotionEvents.get(0).getActionMasked());
- assertEquals(MotionEvent.ACTION_POINTER_DOWN, mMotionEvents.get(1).getActionMasked());
+ // First and last two events are the pointers going down and up
+ assertThat(mMotionEvents.get(0), IS_ACTION_DOWN);
+ assertThat(mMotionEvents.get(1), IS_ACTION_POINTER_DOWN);
+ assertThat(mMotionEvents.get(numEvents - 2), IS_ACTION_POINTER_UP);
+ assertThat(mMotionEvents.get(numEvents - 1), IS_ACTION_UP);
+ // The rest of the events are all moves
+ assertEquals(numEvents - 4, getEventsMatching(IS_ACTION_MOVE).size());
- // The second event must have two pointers at the initial spacing along a 45 degree angle
- MotionEvent firstEventWithTwoPointers = mMotionEvents.get(1);
- assertEquals(2, firstEventWithTwoPointers.getPointerCount());
- MotionEvent.PointerCoords coords0 = new MotionEvent.PointerCoords();
- MotionEvent.PointerCoords coords1 = new MotionEvent.PointerCoords();
- firstEventWithTwoPointers.getPointerCoords(0, coords0);
- firstEventWithTwoPointers.getPointerCoords(1, coords1);
- // Verify center point
- assertEquals((float) centerXInsideView, (coords0.x + coords1.x) / 2, pinchTolerance);
- assertEquals((float) centerYInsideView, (coords0.y + coords1.y) / 2, pinchTolerance);
- // Verify angle
- assertEquals(coords0.x - centerXInsideView, coords0.y - centerYInsideView, pinchTolerance);
- assertEquals(coords1.x - centerXInsideView, coords1.y - centerYInsideView, pinchTolerance);
- // Verify spacing
- assertEquals(startSpacing, distance(coords0, coords1), pinchTolerance);
-
- // The last two events are the pointer up and the final up
- assertEquals(MotionEvent.ACTION_UP, mMotionEvents.get(numEvents - 1).getActionMasked());
-
- MotionEvent lastEventWithTwoPointers = mMotionEvents.get(numEvents - 2);
- assertEquals(MotionEvent.ACTION_POINTER_UP, lastEventWithTwoPointers.getActionMasked());
- lastEventWithTwoPointers.getPointerCoords(0, coords0);
- lastEventWithTwoPointers.getPointerCoords(1, coords1);
- // Verify center point
- assertEquals((float) centerXInsideView, (coords0.x + coords1.x) / 2, pinchTolerance);
- assertEquals((float) centerYInsideView, (coords0.y + coords1.y) / 2, pinchTolerance);
- // Verify angle
- assertEquals(coords0.x - centerXInsideView, coords0.y - centerYInsideView, pinchTolerance);
- assertEquals(coords1.x - centerXInsideView, coords1.y - centerYInsideView, pinchTolerance);
- // Verify spacing
- assertEquals(endSpacing, distance(coords0, coords1), pinchTolerance);
-
+ // All but the first and last events have two pointers
float lastSpacing = startSpacing;
- for (int i = 2; i < numEvents - 2; i++) {
- MotionEvent eventInMiddle = mMotionEvents.get(i);
- assertEquals(MotionEvent.ACTION_MOVE, eventInMiddle.getActionMasked());
- eventInMiddle.getPointerCoords(0, coords0);
- eventInMiddle.getPointerCoords(1, coords1);
+ for (int i = 1; i < numEvents - 1; i++) {
+ MotionEvent.PointerCoords coords0 = new MotionEvent.PointerCoords();
+ MotionEvent.PointerCoords coords1 = new MotionEvent.PointerCoords();
+ MotionEvent event = mMotionEvents.get(i);
+ event.getPointerCoords(0, coords0);
+ event.getPointerCoords(1, coords1);
// Verify center point
- assertEquals((float) centerXInsideView, (coords0.x + coords1.x) / 2, pinchTolerance);
- assertEquals((float) centerYInsideView, (coords0.y + coords1.y) / 2, pinchTolerance);
+ assertEquals((float) centerPoint.x, (coords0.x + coords1.x) / 2, pinchTolerance);
+ assertEquals((float) centerPoint.y, (coords0.y + coords1.y) / 2, pinchTolerance);
// Verify angle
- assertEquals(coords0.x - centerXInsideView, coords0.y - centerYInsideView,
+ assertEquals(coords0.x - centerPoint.x, coords0.y - centerPoint.y,
pinchTolerance);
- assertEquals(coords1.x - centerXInsideView, coords1.y - centerYInsideView,
+ assertEquals(coords1.x - centerPoint.x, coords1.y - centerPoint.y,
pinchTolerance);
float spacing = distance(coords0, coords1);
assertTrue(spacing <= lastSpacing + pinchTolerance);
@@ -336,17 +293,24 @@
// This test assumes device's screen contains its center (W/2, H/2) with some surroundings
// and should work for rectangular, round and round with chin screens.
public void testClickWhenMagnified_matchesActualTouch() throws InterruptedException {
+ final float POINT_TOL = 2.0f;
+ final float CLICK_SHIFT_FROM_CENTER_X = 10;
+ final float CLICK_SHIFT_FROM_CENTER_Y = 20;
+ final float MAGNIFICATION_FACTOR = 2;
if (!mHasTouchScreen) {
return;
}
- final int clickShiftFromCenterX = 10;
- final int clickShiftFromCenterY = 20;
final Resources res = getInstrumentation().getTargetContext().getResources();
final DisplayMetrics metrics = res.getDisplayMetrics();
- final int centerX = metrics.widthPixels / 2;
- final int centerY = metrics.heightPixels / 2;
- final float TOUCH_TOLERANCE = 2.0f;
+ final float centerX = metrics.widthPixels / 2;
+ final float centerY = metrics.heightPixels / 2;
+ final PointF clickPoint = new PointF(
+ centerX + CLICK_SHIFT_FROM_CENTER_X * MAGNIFICATION_FACTOR,
+ centerY + CLICK_SHIFT_FROM_CENTER_Y * MAGNIFICATION_FACTOR);
+ final PointF offsetMagnifiedPointInView = new PointF(
+ centerX + CLICK_SHIFT_FROM_CENTER_X - mViewBounds.left,
+ centerY + CLICK_SHIFT_FROM_CENTER_Y - mViewBounds.top);
StubMagnificationAccessibilityService magnificationService =
StubMagnificationAccessibilityService.enableSelf(this);
@@ -355,19 +319,16 @@
try {
// Magnify screen by 2x with a magnification center in the center of the screen
final AtomicBoolean setScale = new AtomicBoolean();
- final float magnificationFactor = 2.0f;
magnificationService.runOnServiceSync(() -> {
- setScale.set(magnificationController.setScale(magnificationFactor, false));
+ setScale.set(magnificationController.setScale(MAGNIFICATION_FACTOR, false));
magnificationController.setCenter(centerX, centerY, false);
});
assertTrue("Failed to set scale", setScale.get());
- final int clickMagnifiedX = (int) (centerX + magnificationFactor * clickShiftFromCenterX);
- final int clickMagnifiedY = (int) (centerY + magnificationFactor * clickShiftFromCenterY);
- GestureDescription click = createClick(clickMagnifiedX, clickMagnifiedY);
+ GestureDescription click = createClick(clickPoint);
mService.runOnServiceSync(() -> mService.doDispatchGesture(click, mCallback, null));
mCallback.assertGestureCompletes(GESTURE_COMPLETION_TIMEOUT);
- waitForMotionEvents(3);
+ waitForMotionEvents(any(MotionEvent.class), 2);
} finally {
// Reset magnification
final AtomicBoolean result = new AtomicBoolean();
@@ -378,23 +339,136 @@
}
assertEquals(2, mMotionEvents.size());
- MotionEvent clickDown = mMotionEvents.get(0);
- MotionEvent clickUp = mMotionEvents.get(1);
-
- final int centerXInsideView = centerX - mViewBounds.left;
- final int centerYInsideView = centerY - mViewBounds.top;
- final int expectedClickXInsideView = centerXInsideView + clickShiftFromCenterX;
- final int expectedClickYInsideView = centerYInsideView + clickShiftFromCenterY;
- assertEquals(MotionEvent.ACTION_DOWN, clickDown.getActionMasked());
- assertEquals((float) expectedClickXInsideView, clickDown.getX(), TOUCH_TOLERANCE);
- assertEquals((float) expectedClickYInsideView, clickDown.getY(), TOUCH_TOLERANCE);
- assertEquals(clickDown.getDownTime(), clickDown.getEventTime());
-
- assertEquals(MotionEvent.ACTION_UP, clickUp.getActionMasked());
- assertEquals((float) expectedClickXInsideView, clickUp.getX(), TOUCH_TOLERANCE);
- assertEquals((float) expectedClickYInsideView, clickUp.getY(), TOUCH_TOLERANCE);
+ assertThat(mMotionEvents.get(0),
+ both(IS_ACTION_DOWN).and(isAtPoint(offsetMagnifiedPointInView, POINT_TOL)));
+ assertThat(mMotionEvents.get(1),
+ both(IS_ACTION_UP).and(isAtPoint(offsetMagnifiedPointInView, POINT_TOL)));
}
+ public void testContinuedGestures_motionEventsContinue() throws Exception {
+ if (!mHasTouchScreen) {
+ return;
+ }
+
+ Point start = new Point(10, 20);
+ Point mid1 = new Point(20, 20);
+ Point mid2 = new Point(20, 25);
+ Point end = new Point(20, 30);
+ int gestureTime = 500;
+
+ StrokeDescription s1 =
+ lineStrokeInViewBounds(start, mid1, gestureTime, INVALID_STROKE_ID, true);
+ StrokeDescription s2 = lineStrokeInViewBounds(mid1, mid2, gestureTime, s1.getId(), true);
+ StrokeDescription s3 = lineStrokeInViewBounds(mid2, end, gestureTime, s2.getId(), false);
+ GestureDescription gesture1 = new GestureDescription.Builder().addStroke(s1).build();
+ GestureDescription gesture2 = new GestureDescription.Builder().addStroke(s2).build();
+ GestureDescription gesture3 = new GestureDescription.Builder().addStroke(s3).build();
+
+ mService.runOnServiceSync(() -> mService.doDispatchGesture(gesture1, mCallback, null));
+ mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+ mCallback.reset();
+ mService.runOnServiceSync(() -> mService.doDispatchGesture(gesture2, mCallback, null));
+ mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+ mCallback.reset();
+ mService.runOnServiceSync(() -> mService.doDispatchGesture(gesture3, mCallback, null));
+ mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+ waitForMotionEvents(IS_ACTION_UP, 1);
+
+ assertThat(mMotionEvents.get(0), allOf(IS_ACTION_DOWN, isAtPoint(start)));
+ assertThat(mMotionEvents.subList(1, mMotionEvents.size() - 1), everyItem(IS_ACTION_MOVE));
+ assertThat(mMotionEvents, hasItem(isAtPoint(mid1)));
+ assertThat(mMotionEvents, hasItem(isAtPoint(mid2)));
+ assertThat(mMotionEvents.get(mMotionEvents.size() - 1),
+ allOf(IS_ACTION_UP, isAtPoint(end)));
+ }
+
+ public void testContinuedGesture_withLineDisconnect_isCancelled() throws Exception {
+ if (!mHasTouchScreen) {
+ return;
+ }
+
+ Point startPoint = new Point(10, 20);
+ Point midPoint = new Point(20, 20);
+ Point endPoint = new Point(20, 30);
+ int gestureTime = 500;
+
+ StrokeDescription stroke1 = lineStrokeInViewBounds(
+ startPoint, midPoint, gestureTime, INVALID_STROKE_ID, true);
+ GestureDescription gesture1 = new GestureDescription.Builder().addStroke(stroke1).build();
+ mService.runOnServiceSync(() -> mService.doDispatchGesture(gesture1, mCallback, null));
+ mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+ waitForMotionEvents(both(IS_ACTION_MOVE).and(isAtPoint(midPoint)), 1);
+
+ StrokeDescription stroke2 = lineStrokeInViewBounds(endPoint, midPoint, gestureTime,
+ stroke1.getId(), false);
+ GestureDescription gesture2 = new GestureDescription.Builder().addStroke(stroke2).build();
+ mCallback.reset();
+ mMotionEvents.clear();
+ mService.runOnServiceSync(() -> mService.doDispatchGesture(gesture2, mCallback, null));
+ mCallback.assertGestureCancels(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+
+ waitForMotionEvents(IS_ACTION_CANCEL, 1);
+ assertEquals(1, mMotionEvents.size());
+ }
+
+ public void testContinuedGesture_nextGestureDoesntContinue_isCancelled() throws Exception {
+ if (!mHasTouchScreen) {
+ return;
+ }
+
+ Point startPoint = new Point(10, 20);
+ Point midPoint = new Point(20, 20);
+ Point endPoint = new Point(20, 30);
+ int gestureTime = 500;
+
+ StrokeDescription stroke1 = lineStrokeInViewBounds(
+ startPoint, midPoint, gestureTime, INVALID_STROKE_ID, true);
+ GestureDescription gesture1 = new GestureDescription.Builder().addStroke(stroke1).build();
+ mService.runOnServiceSync(() -> mService.doDispatchGesture(gesture1, mCallback, null));
+ mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+
+ StrokeDescription stroke2 = lineStrokeInViewBounds(
+ midPoint, endPoint, gestureTime, INVALID_STROKE_ID, false);
+ GestureDescription gesture2 = new GestureDescription.Builder().addStroke(stroke2).build();
+ mCallback.reset();
+ mService.runOnServiceSync(() -> mService.doDispatchGesture(gesture2, mCallback, null));
+ mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+
+ waitForMotionEvents(IS_ACTION_UP, 1);
+
+ List<MotionEvent> cancelEvent = getEventsMatching(IS_ACTION_CANCEL);
+ assertEquals(1, cancelEvent.size());
+ // Confirm that a down follows the cancel
+ assertThat(mMotionEvents.get(mMotionEvents.indexOf(cancelEvent.get(0)) + 1),
+ both(IS_ACTION_DOWN).and(isAtPoint(midPoint)));
+ // Confirm that the last point is an up
+ assertThat(mMotionEvents.get(mMotionEvents.size() - 1),
+ both(IS_ACTION_UP).and(isAtPoint(endPoint)));
+ }
+
+ public void testContinuingGesture_withNothingToContinue_isCancelled() {
+ if (!mHasTouchScreen) {
+ return;
+ }
+
+ Point startPoint = new Point(10, 20);
+ Point midPoint = new Point(20, 20);
+ Point endPoint = new Point(20, 30);
+ int gestureTime = 500;
+
+ StrokeDescription stroke1 = lineStrokeInViewBounds(
+ startPoint, midPoint, gestureTime, INVALID_STROKE_ID, false);
+ GestureDescription gesture1 = new GestureDescription.Builder().addStroke(stroke1).build();
+ mService.runOnServiceSync(() -> mService.doDispatchGesture(gesture1, mCallback, null));
+ mCallback.assertGestureCompletes(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+
+ StrokeDescription stroke2 = lineStrokeInViewBounds(
+ midPoint, endPoint, gestureTime, stroke1.getId(), false);
+ GestureDescription gesture2 = new GestureDescription.Builder().addStroke(stroke2).build();
+ mCallback.reset();
+ mService.runOnServiceSync(() -> mService.doDispatchGesture(gesture2, mCallback, null));
+ mCallback.assertGestureCancels(gestureTime + GESTURE_COMPLETION_TIMEOUT);
+ }
public static class GestureDispatchActivity extends AccessibilityTestActivity {
public GestureDispatchActivity() {
@@ -433,27 +507,51 @@
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
- assertTrue("Gesture did not complete.", mCompleted);
+ assertTrue("Gesture did not complete. Canceled = " + mCancelled, mCompleted);
+ }
+
+ public synchronized void assertGestureCancels(long timeout) {
+ if (mCancelled) {
+ return;
+ }
+ try {
+ wait(timeout);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ assertTrue("Gesture did not cancel. Completed = " + mCompleted, mCancelled);
+ }
+
+ public synchronized void reset() {
+ mCancelled = false;
+ mCompleted = false;
}
}
- private void waitForMotionEvents(int numEventsExpected) throws InterruptedException {
+ private void waitForMotionEvents(Matcher<MotionEvent> matcher, int numEventsExpected)
+ throws InterruptedException {
synchronized (mMotionEvents) {
long endMillis = SystemClock.uptimeMillis() + MOTION_EVENT_TIMEOUT;
- while ((mMotionEvents.size() < numEventsExpected)
- && (SystemClock.uptimeMillis() < endMillis)) {
+ boolean gotEvents = getEventsMatching(matcher).size() >= numEventsExpected;
+ while (!gotEvents && (SystemClock.uptimeMillis() < endMillis)) {
mMotionEvents.wait(endMillis - SystemClock.uptimeMillis());
+ gotEvents = getEventsMatching(matcher).size() >= numEventsExpected;
}
+ assertTrue("Did not receive required events. Got:\n" + mMotionEvents + "\n filtered:\n"
+ + getEventsMatching(matcher), gotEvents);
}
}
- private void waitForUpEvent() throws InterruptedException {
+ private List<MotionEvent> getEventsMatching(Matcher<MotionEvent> matcher) {
+ List<MotionEvent> events = new ArrayList<>();
synchronized (mMotionEvents) {
- long endMillis = SystemClock.uptimeMillis() + MOTION_EVENT_TIMEOUT;
- while (!mGotUpEvent && (SystemClock.uptimeMillis() < endMillis)) {
- mMotionEvents.wait(endMillis - SystemClock.uptimeMillis());
+ for (MotionEvent event : mMotionEvents) {
+ if (matcher.matches(event)) {
+ events.add(event);
+ }
}
}
+ return events;
}
private float distance(MotionEvent.PointerCoords point1, MotionEvent.PointerCoords point2) {
@@ -474,45 +572,53 @@
}
}
- private GestureDescription createClick(int x, int y) {
+ private GestureDescription createClickInViewBounds(Point clickPoint) {
+ Point offsetClick = new Point(clickPoint);
+ offsetClick.offset(mViewBounds.left, mViewBounds.top);
+ return createClick(offsetClick);
+ }
+
+ private GestureDescription createClick(Point clickPoint) {
+ return createClick(new PointF(clickPoint.x, clickPoint.y));
+ }
+
+ private GestureDescription createClick(PointF clickPoint) {
Path clickPath = new Path();
- clickPath.moveTo(x, y);
- GestureDescription.StrokeDescription clickStroke =
- new GestureDescription.StrokeDescription(clickPath, 0, ViewConfiguration.getTapTimeout());
+ clickPath.moveTo(clickPoint.x, clickPoint.y);
+ StrokeDescription clickStroke =
+ new StrokeDescription(clickPath, 0, ViewConfiguration.getTapTimeout());
GestureDescription.Builder clickBuilder = new GestureDescription.Builder();
clickBuilder.addStroke(clickStroke);
return clickBuilder.build();
}
- private GestureDescription createLongClick(int x, int y) {
+ private GestureDescription createLongClickInViewBounds(Point clickPoint) {
+ Point offsetPoint = new Point(clickPoint);
+ offsetPoint.offset(mViewBounds.left, mViewBounds.top);
Path clickPath = new Path();
- clickPath.moveTo(x, y);
+ clickPath.moveTo(offsetPoint.x, offsetPoint.y);
int longPressTime = ViewConfiguration.getLongPressTimeout();
- GestureDescription.StrokeDescription longClickStroke =
- new GestureDescription.StrokeDescription(clickPath, 0, longPressTime + (longPressTime / 2));
+ StrokeDescription longClickStroke =
+ new StrokeDescription(clickPath, 0, longPressTime + (longPressTime / 2));
GestureDescription.Builder longClickBuilder = new GestureDescription.Builder();
longClickBuilder.addStroke(longClickStroke);
return longClickBuilder.build();
}
- private GestureDescription createSwipe(
- int startX, int startY, int endX, int endY, long duration) {
- Path swipePath = new Path();
- swipePath.moveTo(startX, startY);
- swipePath.lineTo(endX, endY);
-
- GestureDescription.StrokeDescription swipeStroke = new GestureDescription.StrokeDescription(swipePath, 0, duration);
- GestureDescription.Builder swipeBuilder = new GestureDescription.Builder();
- swipeBuilder.addStroke(swipeStroke);
- return swipeBuilder.build();
+ private GestureDescription createSwipeInViewBounds(Point start, Point end, long duration) {
+ return new GestureDescription.Builder()
+ .addStroke(lineStrokeInViewBounds(start, end, duration, INVALID_STROKE_ID, false))
+ .build();
}
- private GestureDescription createPinch(int centerX, int centerY, int startSpacing,
+ private GestureDescription createPinchInViewBounds(Point centerPoint, int startSpacing,
int endSpacing, float orientation, long duration) {
if ((startSpacing < 0) || (endSpacing < 0)) {
throw new IllegalArgumentException("Pinch spacing cannot be negative");
}
+ Point offsetCenter = new Point(centerPoint);
+ offsetCenter.offset(mViewBounds.left, mViewBounds.top);
float[] startPoint1 = new float[2];
float[] endPoint1 = new float[2];
float[] startPoint2 = new float[2];
@@ -531,7 +637,7 @@
/* Rotate and translate the points */
Matrix matrix = new Matrix();
matrix.setRotate(orientation);
- matrix.postTranslate(centerX, centerY);
+ matrix.postTranslate(offsetCenter.x, offsetCenter.y);
matrix.mapPoints(startPoint1);
matrix.mapPoints(endPoint1);
matrix.mapPoints(startPoint2);
@@ -544,11 +650,57 @@
path2.moveTo(startPoint2[0], startPoint2[1]);
path2.lineTo(endPoint2[0], endPoint2[1]);
- GestureDescription.StrokeDescription path1Stroke = new GestureDescription.StrokeDescription(path1, 0, duration);
- GestureDescription.StrokeDescription path2Stroke = new GestureDescription.StrokeDescription(path2, 0, duration);
+ StrokeDescription path1Stroke = new StrokeDescription(path1, 0, duration);
+ StrokeDescription path2Stroke = new StrokeDescription(path2, 0, duration);
GestureDescription.Builder swipeBuilder = new GestureDescription.Builder();
swipeBuilder.addStroke(path1Stroke);
swipeBuilder.addStroke(path2Stroke);
return swipeBuilder.build();
}
+
+ StrokeDescription lineStrokeInViewBounds(Point startPoint, Point endPoint, long duration,
+ int continuedStroke, boolean isContinued) {
+ Path path = new Path();
+ path.moveTo(startPoint.x + mViewBounds.left, startPoint.y + mViewBounds.top);
+ path.lineTo(endPoint.x + mViewBounds.left, endPoint.y + mViewBounds.top);
+ return new StrokeDescription(path, 0, duration, continuedStroke, isContinued);
+ }
+
+ private static class MotionEventActionMatcher extends TypeSafeMatcher<MotionEvent> {
+ int mAction;
+
+ MotionEventActionMatcher(int action) {
+ super();
+ mAction = action;
+ }
+
+ @Override
+ protected boolean matchesSafely(MotionEvent motionEvent) {
+ return motionEvent.getActionMasked() == mAction;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Matching to action " + mAction);
+ }
+ }
+
+
+ Matcher<MotionEvent> isAtPoint(final Point point) {
+ return isAtPoint(new PointF(point.x, point.y), 0.01f);
+ }
+
+ Matcher<MotionEvent> isAtPoint(final PointF point, final float tol) {
+ return new TypeSafeMatcher<MotionEvent>() {
+ @Override
+ protected boolean matchesSafely(MotionEvent event) {
+ return Math.hypot(event.getX() - point.x, event.getY() - point.y) < tol;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("Matching to point " + point);
+ }
+ };
+ }
}
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
index 234f66a..b1c37cf7 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/GestureDescriptionTest.java
@@ -15,10 +15,14 @@
package android.accessibilityservice.cts;
import android.accessibilityservice.GestureDescription;
+import android.accessibilityservice.GestureDescription.StrokeDescription;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.test.InstrumentationTestCase;
+import static android.accessibilityservice.GestureDescription.StrokeDescription.INVALID_STROKE_ID;
+import static android.test.MoreAsserts.assertNotEqual;
+
/**
* Tests for creating gesture descriptions.
*/
@@ -35,7 +39,7 @@
public void testCreateStroke_noDuration_shouldThrow() {
try {
- new GestureDescription.StrokeDescription(mNominalPath, 0, 0);
+ new StrokeDescription(mNominalPath, 0, 0);
fail("Missing exception for stroke with no duration.");
} catch (IllegalArgumentException e) {
}
@@ -43,7 +47,7 @@
public void testCreateStroke_negativeStartTime_shouldThrow() {
try {
- new GestureDescription.StrokeDescription(mNominalPath, -1, NOMINAL_PATH_DURATION);
+ new StrokeDescription(mNominalPath, -1, NOMINAL_PATH_DURATION);
fail("Missing exception for stroke with negative start time.");
} catch (IllegalArgumentException e) {
}
@@ -54,7 +58,7 @@
negativeStartXPath.moveTo(-1, 0);
negativeStartXPath.lineTo(10, 10);
try {
- new GestureDescription.StrokeDescription(negativeStartXPath, 0, NOMINAL_PATH_DURATION);
+ new StrokeDescription(negativeStartXPath, 0, NOMINAL_PATH_DURATION);
fail("Missing exception for stroke with negative start x coord.");
} catch (IllegalArgumentException e) {
}
@@ -65,7 +69,7 @@
negativeStartYPath.moveTo(0, -1);
negativeStartYPath.lineTo(10, 10);
try {
- new GestureDescription.StrokeDescription(negativeStartYPath, 0, NOMINAL_PATH_DURATION);
+ new StrokeDescription(negativeStartYPath, 0, NOMINAL_PATH_DURATION);
fail("Missing exception for stroke with negative start y coord.");
} catch (IllegalArgumentException e) {
}
@@ -76,7 +80,7 @@
negativeEndXPath.moveTo(0, 0);
negativeEndXPath.lineTo(-10, 10);
try {
- new GestureDescription.StrokeDescription(negativeEndXPath, 0, NOMINAL_PATH_DURATION);
+ new StrokeDescription(negativeEndXPath, 0, NOMINAL_PATH_DURATION);
fail("Missing exception for stroke with negative end x coord.");
} catch (IllegalArgumentException e) {
}
@@ -87,7 +91,7 @@
negativeEndYPath.moveTo(0, 0);
negativeEndYPath.lineTo(10, -10);
try {
- new GestureDescription.StrokeDescription(negativeEndYPath, 0, NOMINAL_PATH_DURATION);
+ new StrokeDescription(negativeEndYPath, 0, NOMINAL_PATH_DURATION);
fail("Missing exception for stroke with negative end y coord.");
} catch (IllegalArgumentException e) {
}
@@ -96,7 +100,7 @@
public void testCreateStroke_withEmptyPath_shouldThrow() {
Path emptyPath = new Path();
try {
- new GestureDescription.StrokeDescription(emptyPath, 0, NOMINAL_PATH_DURATION);
+ new StrokeDescription(emptyPath, 0, NOMINAL_PATH_DURATION);
fail("Missing exception for empty path.");
} catch (IllegalArgumentException e) {
}
@@ -109,27 +113,48 @@
multiContourPath.moveTo(20, 0);
multiContourPath.lineTo(20, 10);
try {
- new GestureDescription.StrokeDescription(multiContourPath, 0, NOMINAL_PATH_DURATION);
+ new StrokeDescription(multiContourPath, 0, NOMINAL_PATH_DURATION);
fail("Missing exception for stroke with multi-contour path.");
} catch (IllegalArgumentException e) {
}
}
+ public void testStrokeDescriptionGettersForContinuation() {
+ StrokeDescription strokeDescription = new StrokeDescription(mNominalPath, 0, 100);
+ assertFalse(strokeDescription.isContinued());
+
+ strokeDescription = new StrokeDescription(mNominalPath, 0, 100, INVALID_STROKE_ID, true);
+ assertTrue(strokeDescription.isContinued());
+
+ strokeDescription = new StrokeDescription(mNominalPath, 0, 100, INVALID_STROKE_ID, false);
+ assertFalse(strokeDescription.isContinued());
+
+ int idOfContinuedStroke = strokeDescription.getId() - 1;
+ strokeDescription = new StrokeDescription(mNominalPath, 0, 100, idOfContinuedStroke, false);
+ assertEquals(idOfContinuedStroke, strokeDescription.getContinuedStrokeId());
+ }
+
+ public void testStrokeDescriptionIds() {
+ StrokeDescription strokeDescription1 =
+ new StrokeDescription(mNominalPath, 0, 100);
+ StrokeDescription strokeDescription2 =
+ new StrokeDescription(mNominalPath, 0, 100);
+ assertNotEqual(strokeDescription1.getId(), strokeDescription2.getId());
+ }
+
public void testAddStroke_allowUpToMaxPaths() {
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
for (int i = 0; i < GestureDescription.getMaxStrokeCount(); i++) {
Path path = new Path();
path.moveTo(i, i);
path.lineTo(10 + i, 10 + i);
- gestureBuilder.addStroke(
- new GestureDescription.StrokeDescription(path, 0, NOMINAL_PATH_DURATION));
+ gestureBuilder.addStroke(new StrokeDescription(path, 0, NOMINAL_PATH_DURATION));
}
Path path = new Path();
path.moveTo(10, 10);
path.lineTo(20, 20);
try {
- gestureBuilder.addStroke(
- new GestureDescription.StrokeDescription(path, 0, NOMINAL_PATH_DURATION));
+ gestureBuilder.addStroke(new StrokeDescription(path, 0, NOMINAL_PATH_DURATION));
fail("Missing exception for adding too many strokes.");
} catch (RuntimeException e) {
}
@@ -141,8 +166,8 @@
path.lineTo(20, 20);
GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
try {
- gestureBuilder.addStroke(new GestureDescription.StrokeDescription(
- path, 0, GestureDescription.getMaxGestureDuration() + 1));
+ gestureBuilder.addStroke(
+ new StrokeDescription(path, 0, GestureDescription.getMaxGestureDuration() + 1));
fail("Missing exception for adding stroke with duration too long.");
} catch (RuntimeException e) {
}
@@ -166,7 +191,7 @@
Path path = new Path();
path.moveTo(x, startY);
path.lineTo(x, endY);
- GestureDescription.StrokeDescription strokeDescription = new GestureDescription.StrokeDescription(path, start, duration);
+ StrokeDescription strokeDescription = new StrokeDescription(path, start, duration);
GestureDescription.Builder builder = new GestureDescription.Builder();
builder.addStroke(strokeDescription);
diff --git a/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java b/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
index 4a9ce08..31c78c5 100644
--- a/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
+++ b/tests/accessibilityservice/src/android/accessibilityservice/cts/InstrumentedAccessibilityService.java
@@ -30,6 +30,9 @@
sInstances = new HashMap<>();
private final Handler mHandler = new Handler();
+ final Object mInterruptWaitObject = new Object();
+ public boolean mOnInterruptCalled;
+
@Override
protected void onServiceConnected() {
@@ -53,7 +56,10 @@
@Override
public void onInterrupt() {
- // Stub method.
+ synchronized (mInterruptWaitObject) {
+ mOnInterruptCalled = true;
+ mInterruptWaitObject.notifyAll();
+ }
}
public void disableSelfAndRemove() {
@@ -70,6 +76,16 @@
assertTrue("Timed out waiting for runOnServiceSync()", sr.waitForComplete());
}
+ public boolean wasOnInterruptCalled() {
+ synchronized (mInterruptWaitObject) {
+ return mOnInterruptCalled;
+ }
+ }
+
+ public Object getInterruptWaitObject() {
+ return mInterruptWaitObject;
+ }
+
private static final class SyncRunnable implements Runnable {
private final CountDownLatch mLatch = new CountDownLatch(1);
private final Runnable mTarget;
diff --git a/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java b/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java
index 81ea503..b7d2895 100644
--- a/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java
+++ b/tests/admin/src/android/admin/cts/DeviceAdminReceiverTest.java
@@ -29,6 +29,8 @@
private static final String TAG = DeviceAdminReceiverTest.class.getSimpleName();
private static final String DISABLE_WARNING = "Disable Warning";
private static final String BUGREPORT_HASH = "f4k3h45h";
+ private static final long NETWORK_LOGS_TOKEN = 0L;
+ private static final int NETWORK_LOGS_COUNT = 0;
private static final String ACTION_BUGREPORT_SHARING_DECLINED =
"android.app.action.BUGREPORT_SHARING_DECLINED";
@@ -41,6 +43,13 @@
"android.app.extra.BUGREPORT_FAILURE_REASON";
private static final String EXTRA_BUGREPORT_HASH = "android.app.extra.BUGREPORT_HASH";
+ private static final String ACTION_NETWORK_LOGS_AVAILABLE
+ = "android.app.action.NETWORK_LOGS_AVAILABLE";
+ private static final String EXTRA_NETWORK_LOGS_TOKEN =
+ "android.app.extra.EXTRA_NETWORK_LOGS_TOKEN";
+ private static final String EXTRA_NETWORK_LOGS_COUNT =
+ "android.app.extra.EXTRA_NETWORK_LOGS_COUNT";
+
private static final int PASSWORD_CHANGED = 0x1;
private static final int PASSWORD_FAILED = 0x2;
private static final int PASSWORD_SUCCEEDED = 0x4;
@@ -51,6 +60,7 @@
private static final int BUGREPORT_FAILED = 0x80;
private static final int BUGREPORT_SHARED = 0x100;
private static final int SECURITY_LOGS_AVAILABLE = 0x200;
+ private static final int NETWORK_LOGS_AVAILABLE = 0x400;
private TestReceiver mReceiver;
private boolean mDeviceAdmin;
@@ -112,6 +122,15 @@
mReceiver.reset();
mReceiver.onReceive(mContext, new Intent(ACTION_SECURITY_LOGS_AVAILABLE));
assertTrue(mReceiver.hasFlags(SECURITY_LOGS_AVAILABLE));
+
+ mReceiver.reset();
+ Intent networkLogsAvailableIntent = new Intent(ACTION_NETWORK_LOGS_AVAILABLE);
+ networkLogsAvailableIntent.putExtra(EXTRA_NETWORK_LOGS_TOKEN, NETWORK_LOGS_TOKEN);
+ networkLogsAvailableIntent.putExtra(EXTRA_NETWORK_LOGS_COUNT, NETWORK_LOGS_COUNT);
+ mReceiver.onReceive(mContext, networkLogsAvailableIntent);
+ assertTrue(mReceiver.hasFlags(NETWORK_LOGS_AVAILABLE));
+ assertEquals(NETWORK_LOGS_TOKEN, mReceiver.getNetworkLogsToken());
+ assertEquals(NETWORK_LOGS_COUNT, mReceiver.getNetworkLogsCount());
}
private class TestReceiver extends DeviceAdminReceiver {
@@ -119,10 +138,14 @@
private int mFlags = 0;
private int bugreportFailureCode = -1;
private String bugreportHash;
+ private long networkLogsToken = -1L;
+ private int networkLogsCount = -1;
void reset() {
mFlags = 0;
bugreportFailureCode = -1;
+ networkLogsToken = -1L;
+ networkLogsCount = -1;
bugreportHash = null;
}
@@ -138,6 +161,14 @@
return bugreportHash;
}
+ long getNetworkLogsToken() {
+ return networkLogsToken;
+ }
+
+ int getNetworkLogsCount() {
+ return networkLogsCount;
+ }
+
@Override
public void onPasswordChanged(Context context, Intent intent) {
super.onPasswordChanged(context, intent);
@@ -199,5 +230,14 @@
super.onSecurityLogsAvailable(context, intent);
mFlags |= SECURITY_LOGS_AVAILABLE;
}
+
+ @Override
+ public void onNetworkLogsAvailable(Context context, Intent intent, long batchToken,
+ int networkLogsCount) {
+ super.onNetworkLogsAvailable(context, intent, batchToken, networkLogsCount);
+ mFlags |= NETWORK_LOGS_AVAILABLE;
+ this.networkLogsToken = batchToken;
+ this.networkLogsCount = networkLogsCount;
+ }
}
}
diff --git a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index deb1854..aa4a688 100644
--- a/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -174,6 +174,44 @@
}
}
+ public void testSetNetworkLoggingEnabled_failIfNotDeviceOwner() {
+ if (!mDeviceAdmin) {
+ Log.w(TAG, "Skipping testSetNetworkLoggingEnabled_failIfNotDeviceOwner");
+ return;
+ }
+ try {
+ mDevicePolicyManager.setNetworkLoggingEnabled(mComponent, true);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertDeviceOwnerMessage(e.getMessage());
+ }
+ }
+
+ public void testIsNetworkLoggingEnabled_failIfNotDeviceOwner() {
+ if (!mDeviceAdmin) {
+ Log.w(TAG, "Skipping testIsNetworkLoggingEnabled_failIfNotDeviceOwner");
+ return;
+ }
+ try {
+ mDevicePolicyManager.isNetworkLoggingEnabled(mComponent);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertDeviceOwnerMessage(e.getMessage());
+ }
+ }
+
+ public void testRetrieveNetworkLogs_failIfNotDeviceOwner() {
+ if (!mDeviceAdmin) {
+ Log.w(TAG, "Skipping testRetrieveNetworkLogs_failIfNotDeviceOwner");
+ return;
+ }
+ try {
+ mDevicePolicyManager.retrieveNetworkLogs(mComponent, /* batchToken */ 0);
+ fail("did not throw expected SecurityException");
+ } catch (SecurityException e) {
+ assertDeviceOwnerMessage(e.getMessage());
+ }
+ }
public void testRemoveUser_failIfNotDeviceOwner() {
if (!mDeviceAdmin) {
Log.w(TAG, "Skipping testRemoveUser_failIfNotDeviceOwner");
diff --git a/tests/app/src/android/app/cts/NotificationChannelTest.java b/tests/app/src/android/app/cts/NotificationChannelTest.java
index a196e1e..cf96532 100644
--- a/tests/app/src/android/app/cts/NotificationChannelTest.java
+++ b/tests/app/src/android/app/cts/NotificationChannelTest.java
@@ -70,12 +70,21 @@
public void testVibration() {
NotificationChannel channel =
new NotificationChannel("1", "one", NotificationManager.IMPORTANCE_DEFAULT);
- channel.setVibration(true);
+ channel.enableVibration(true);
assertTrue(channel.shouldVibrate());
- channel.setVibration(false);
+ channel.enableVibration(false);
assertFalse(channel.shouldVibrate());
}
+ public void testVibrationPattern() {
+ final long[] pattern = new long[] {1, 7, 1, 7, 3};
+ NotificationChannel channel =
+ new NotificationChannel("1", "one", NotificationManager.IMPORTANCE_DEFAULT);
+ assertNull(channel.getVibrationPattern());
+ channel.setVibrationPattern(pattern);
+ assertEquals(pattern, channel.getVibrationPattern());
+ }
+
public void testRingtone() {
Uri expected = new Uri.Builder().scheme("fruit").appendQueryParameter("favorite", "bananas")
.build();
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index ccd86fab..6e26dd2 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -20,6 +20,7 @@
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
+import android.app.stubs.R;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -27,8 +28,9 @@
import android.service.notification.StatusBarNotification;
import android.test.AndroidTestCase;
import android.util.Log;
+import java.util.concurrent.CountDownLatch;
-import android.app.stubs.R;
+import java.util.Arrays;
public class NotificationManagerTest extends AndroidTestCase {
final String TAG = NotificationManagerTest.class.getSimpleName();
@@ -51,19 +53,26 @@
mNotificationManager.cancelAll();
}
- public void testCreateChannel() {
- NotificationChannel channel =
+ public void testCreateChannel() throws InterruptedException {
+ final NotificationChannel channel =
new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
- channel.setVibration(true);
+ channel.enableVibration(true);
+ channel.setVibrationPattern(new long[] {5, 8, 2, 1});
channel.setSound(new Uri.Builder().scheme("test").build());
channel.setLights(true);
channel.setBypassDnd(true);
channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
try {
- mNotificationManager.createNotificationChannel(channel);
- NotificationChannel created =
- mNotificationManager.getNotificationChannel(channel.getId());
- compareChannels(channel, created);
+ final CountDownLatch latch = new CountDownLatch(1);
+ mNotificationManager.createNotificationChannel(
+ channel,
+ (createdChannel) -> {
+ compareChannels(channel, createdChannel);
+ latch.countDown();
+ },
+ null);
+ // Verify that the Listener was executed.
+ latch.await();
} finally {
mNotificationManager.deleteNotificationChannel(channel.getId());
}
@@ -73,10 +82,11 @@
NotificationChannel channel =
new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
try {
- mNotificationManager.createNotificationChannel(channel);
+ mNotificationManager.createNotificationChannel(channel, (createdChannel) -> {}, null);
compareChannels(channel, mNotificationManager.getNotificationChannel(channel.getId()));
try {
- mNotificationManager.createNotificationChannel(channel);
+ mNotificationManager.createNotificationChannel(channel, (createdChannel) -> {},
+ null);
fail("Created channel with duplicate id");
} catch (IllegalArgumentException e) {
// success
@@ -90,7 +100,7 @@
NotificationChannel channel =
new NotificationChannel("id2", "name", NotificationManager.IMPORTANCE_UNSPECIFIED);
try {
- mNotificationManager.createNotificationChannel(channel);
+ mNotificationManager.createNotificationChannel(channel, (createdChannel) -> {}, null);
} catch (IllegalArgumentException e) {
//success
}
@@ -99,7 +109,7 @@
public void testDeleteChannel() {
NotificationChannel channel =
new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_LOW);
- mNotificationManager.createNotificationChannel(channel);
+ mNotificationManager.createNotificationChannel(channel, (createdChannel) -> {}, null);
compareChannels(channel, mNotificationManager.getNotificationChannel(channel.getId()));
mNotificationManager.deleteNotificationChannel(channel.getId());
assertNull(mNotificationManager.getNotificationChannel(channel.getId()));
@@ -124,10 +134,10 @@
NotificationChannel channel4 =
new NotificationChannel("id4", "name4", NotificationManager.IMPORTANCE_MIN);
try {
- mNotificationManager.createNotificationChannel(channel1);
- mNotificationManager.createNotificationChannel(channel2);
- mNotificationManager.createNotificationChannel(channel3);
- mNotificationManager.createNotificationChannel(channel4);
+ mNotificationManager.createNotificationChannel(channel1, (createdChannel) -> {}, null);
+ mNotificationManager.createNotificationChannel(channel2, (createdChannel) -> {}, null);
+ mNotificationManager.createNotificationChannel(channel3, (createdChannel) -> {}, null);
+ mNotificationManager.createNotificationChannel(channel4, (createdChannel) -> {}, null);
compareChannels(channel2,
mNotificationManager.getNotificationChannel(channel2.getId()));
@@ -217,7 +227,8 @@
}
private boolean checkNotificationExistence(int id, boolean shouldExist) {
- // notification is a bit asynchronous so it may take a few ms to appear in getActiveNotifications()
+ // notification is a bit asynchronous so it may take a few ms to appear in
+ // getActiveNotifications()
// we will check for it for up to 200ms before giving up
boolean found = false;
for (int tries=3; tries-->0;) {
@@ -241,6 +252,14 @@
}
private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
+ if (actual == null) {
+ fail("actual channel is null");
+ return;
+ }
+ if (expected == null) {
+ fail("expected channel is null");
+ return;
+ }
assertEquals(expected.getId(), actual.getId());
assertEquals(expected.getName(), actual.getName());
assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
@@ -249,5 +268,6 @@
assertEquals(expected.getLockscreenVisibility(), actual.getLockscreenVisibility());
assertEquals(expected.getSound(), actual.getSound());
assertEquals(expected.canBypassDnd(), actual.canBypassDnd());
+ assertTrue(Arrays.equals(expected.getVibrationPattern(), actual.getVibrationPattern()));
}
}
diff --git a/tests/app/src/android/app/cts/SystemFeaturesTest.java b/tests/app/src/android/app/cts/SystemFeaturesTest.java
index aca79fc..1a6bf4c 100644
--- a/tests/app/src/android/app/cts/SystemFeaturesTest.java
+++ b/tests/app/src/android/app/cts/SystemFeaturesTest.java
@@ -467,6 +467,10 @@
}
public void testUsbAccessory() {
+ // USB accessory mode is only a requirement for devices with USB ports supporting
+ // peripheral mode. As there is no public API to distinguish a device with only host
+ // mode support from having both peripheral and host support, the test may have
+ // false negatives.
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) &&
!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION) &&
!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
diff --git a/tests/backup/src/android/backup/cts/BackupQuotaTest.java b/tests/backup/src/android/backup/cts/BackupQuotaTest.java
index bec28c7..0493993 100644
--- a/tests/backup/src/android/backup/cts/BackupQuotaTest.java
+++ b/tests/backup/src/android/backup/cts/BackupQuotaTest.java
@@ -17,6 +17,7 @@
package android.backup.cts;
import android.app.Instrumentation;
+import android.content.pm.PackageManager;
import android.os.ParcelFileDescriptor;
import android.test.InstrumentationTestCase;
import android.util.Log;
@@ -46,18 +47,21 @@
private static final int SMALL_LOGCAT_DELAY = 1000;
- private boolean localTransportIsPresent;
+ private boolean isBackupSupported;
private boolean wasBackupEnabled;
private String oldTransport;
@Override
protected void setUp() throws Exception {
super.setUp();
- localTransportIsPresent = hasBackupTransport(LOCAL_TRANSPORT);
- if (!localTransportIsPresent) {
+ PackageManager packageManager = getInstrumentation().getContext().getPackageManager();
+ isBackupSupported = packageManager != null
+ && packageManager.hasSystemFeature(PackageManager.FEATURE_BACKUP);
+ if (!isBackupSupported) {
return;
}
// Enable backup and select local backup transport
+ assertTrue("LocalTransport should be available.", hasBackupTransport(LOCAL_TRANSPORT));
wasBackupEnabled = enableBackup(true);
oldTransport = setBackupTransport(LOCAL_TRANSPORT);
}
@@ -65,7 +69,7 @@
@Override
protected void tearDown() throws Exception {
// Return old transport
- if (localTransportIsPresent) {
+ if (isBackupSupported) {
setBackupTransport(oldTransport);
enableBackup(wasBackupEnabled);
}
@@ -73,7 +77,7 @@
}
public void testQuotaExceeded() throws Exception {
- if (!localTransportIsPresent) {
+ if (!isBackupSupported) {
return;
}
exec("logcat --clear");
diff --git a/tests/core/Android.mk b/tests/core/Android.mk
index e9c9793..7a2a708 100644
--- a/tests/core/Android.mk
+++ b/tests/core/Android.mk
@@ -14,4 +14,6 @@
LOCAL_PATH:= $(call my-dir)
+BUILD_CTSCORE_PACKAGE:=$(LOCAL_PATH)/ctscore.mk
+
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/core/libcore/Android.mk b/tests/core/libcore/Android.mk
deleted file mode 100644
index 5a897eb8..0000000
--- a/tests/core/libcore/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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)
-
-BUILD_CTSCORE_PACKAGE:=$(LOCAL_PATH)/../ctscore.mk
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/core/libcore/com/Android.mk b/tests/core/libcore/com/Android.mk
deleted file mode 100644
index db08dbd..0000000
--- a/tests/core/libcore/com/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.com
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/com/AndroidManifest.xml b/tests/core/libcore/com/AndroidManifest.xml
deleted file mode 100644
index 8790a7e..0000000
--- a/tests/core/libcore/com/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.com">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data
- android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/conscrypt/Android.mk b/tests/core/libcore/conscrypt/Android.mk
deleted file mode 100644
index 7428bf0..0000000
--- a/tests/core/libcore/conscrypt/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.conscrypt
-LOCAL_STATIC_JAVA_LIBRARIES := conscrypt-tests mockito-target-minus-junit4
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/conscrypt/AndroidManifest.xml b/tests/core/libcore/conscrypt/AndroidManifest.xml
deleted file mode 100644
index b299793..0000000
--- a/tests/core/libcore/conscrypt/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.conscrypt">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/dalvik/Android.mk b/tests/core/libcore/dalvik/Android.mk
deleted file mode 100644
index 42d14f3..0000000
--- a/tests/core/libcore/dalvik/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.dalvik
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/dalvik/AndroidManifest.xml b/tests/core/libcore/dalvik/AndroidManifest.xml
deleted file mode 100644
index ca34678..0000000
--- a/tests/core/libcore/dalvik/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.dalvik">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data
- android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_annotation/Android.mk b/tests/core/libcore/harmony_annotation/Android.mk
deleted file mode 100644
index e9f716e..0000000
--- a/tests/core/libcore/harmony_annotation/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_annotation
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_annotation/AndroidManifest.xml b/tests/core/libcore/harmony_annotation/AndroidManifest.xml
deleted file mode 100644
index c83ecf2..0000000
--- a/tests/core/libcore/harmony_annotation/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_annotation">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data
- android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_beans/Android.mk b/tests/core/libcore/harmony_beans/Android.mk
deleted file mode 100644
index 2131ae0..0000000
--- a/tests/core/libcore/harmony_beans/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_beans
-LOCAL_STATIC_JAVA_LIBRARIES := apache-harmony-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_beans/AndroidManifest.xml b/tests/core/libcore/harmony_beans/AndroidManifest.xml
deleted file mode 100644
index b9b161c..0000000
--- a/tests/core/libcore/harmony_beans/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_beans">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data
- android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_java_io/Android.mk b/tests/core/libcore/harmony_java_io/Android.mk
deleted file mode 100644
index a8d4fa0..0000000
--- a/tests/core/libcore/harmony_java_io/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_io
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_io/AndroidManifest.xml b/tests/core/libcore/harmony_java_io/AndroidManifest.xml
deleted file mode 100644
index e69d4b4..0000000
--- a/tests/core/libcore/harmony_java_io/AndroidManifest.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_java_io">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data
- android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_java_lang/Android.mk b/tests/core/libcore/harmony_java_lang/Android.mk
deleted file mode 100644
index 8b1bdff..0000000
--- a/tests/core/libcore/harmony_java_lang/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_lang
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_lang/AndroidManifest.xml b/tests/core/libcore/harmony_java_lang/AndroidManifest.xml
deleted file mode 100644
index 1a5a748..0000000
--- a/tests/core/libcore/harmony_java_lang/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_java_lang">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_java_math/Android.mk b/tests/core/libcore/harmony_java_math/Android.mk
deleted file mode 100644
index 8310743..0000000
--- a/tests/core/libcore/harmony_java_math/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_math
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_math/AndroidManifest.xml b/tests/core/libcore/harmony_java_math/AndroidManifest.xml
deleted file mode 100644
index 4cdf654..0000000
--- a/tests/core/libcore/harmony_java_math/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_java_math">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_java_net/Android.mk b/tests/core/libcore/harmony_java_net/Android.mk
deleted file mode 100644
index 7917bcc..0000000
--- a/tests/core/libcore/harmony_java_net/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_net
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_net/AndroidManifest.xml b/tests/core/libcore/harmony_java_net/AndroidManifest.xml
deleted file mode 100644
index db14fa9..0000000
--- a/tests/core/libcore/harmony_java_net/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_java_net">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_java_nio/Android.mk b/tests/core/libcore/harmony_java_nio/Android.mk
deleted file mode 100644
index 2c6f673..0000000
--- a/tests/core/libcore/harmony_java_nio/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_nio
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_nio/AndroidManifest.xml b/tests/core/libcore/harmony_java_nio/AndroidManifest.xml
deleted file mode 100644
index 0221ebb..0000000
--- a/tests/core/libcore/harmony_java_nio/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_java_nio">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_java_text/Android.mk b/tests/core/libcore/harmony_java_text/Android.mk
deleted file mode 100644
index ecd1574..0000000
--- a/tests/core/libcore/harmony_java_text/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_text
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_text/AndroidManifest.xml b/tests/core/libcore/harmony_java_text/AndroidManifest.xml
deleted file mode 100644
index 6818053..0000000
--- a/tests/core/libcore/harmony_java_text/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_java_text">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_java_util/Android.mk b/tests/core/libcore/harmony_java_util/Android.mk
deleted file mode 100644
index 6d7bded..0000000
--- a/tests/core/libcore/harmony_java_util/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_java_util
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_java_util/AndroidManifest.xml b/tests/core/libcore/harmony_java_util/AndroidManifest.xml
deleted file mode 100644
index e36468e..0000000
--- a/tests/core/libcore/harmony_java_util/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_java_util">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_javax_security/Android.mk b/tests/core/libcore/harmony_javax_security/Android.mk
deleted file mode 100644
index 011940d..0000000
--- a/tests/core/libcore/harmony_javax_security/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_javax_security
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_javax_security/AndroidManifest.xml b/tests/core/libcore/harmony_javax_security/AndroidManifest.xml
deleted file mode 100644
index c927855..0000000
--- a/tests/core/libcore/harmony_javax_security/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_javax_security">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_logging/Android.mk b/tests/core/libcore/harmony_logging/Android.mk
deleted file mode 100644
index 2ec10f1..0000000
--- a/tests/core/libcore/harmony_logging/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_logging
-LOCAL_STATIC_JAVA_LIBRARIES := apache-harmony-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_logging/AndroidManifest.xml b/tests/core/libcore/harmony_logging/AndroidManifest.xml
deleted file mode 100644
index 8a669e2..0000000
--- a/tests/core/libcore/harmony_logging/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_logging">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_prefs/Android.mk b/tests/core/libcore/harmony_prefs/Android.mk
deleted file mode 100644
index 92b0c7d..0000000
--- a/tests/core/libcore/harmony_prefs/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_prefs
-LOCAL_STATIC_JAVA_LIBRARIES := apache-harmony-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_prefs/AndroidManifest.xml b/tests/core/libcore/harmony_prefs/AndroidManifest.xml
deleted file mode 100644
index ebcb4ef..0000000
--- a/tests/core/libcore/harmony_prefs/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_prefs">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/harmony_sql/Android.mk b/tests/core/libcore/harmony_sql/Android.mk
deleted file mode 100644
index b1df215..0000000
--- a/tests/core/libcore/harmony_sql/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.harmony_sql
-LOCAL_STATIC_JAVA_LIBRARIES := apache-harmony-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/harmony_sql/AndroidManifest.xml b/tests/core/libcore/harmony_sql/AndroidManifest.xml
deleted file mode 100644
index 7cd86da..0000000
--- a/tests/core/libcore/harmony_sql/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.harmony_sql">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/jsr166/Android.mk b/tests/core/libcore/jsr166/Android.mk
deleted file mode 100644
index 3f9871e..0000000
--- a/tests/core/libcore/jsr166/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.jsr166
-LOCAL_STATIC_JAVA_LIBRARIES := jsr166-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/jsr166/AndroidManifest.xml b/tests/core/libcore/jsr166/AndroidManifest.xml
deleted file mode 100644
index fb4a648..0000000
--- a/tests/core/libcore/jsr166/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.jsr166">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/libcore/Android.mk b/tests/core/libcore/libcore/Android.mk
deleted file mode 100644
index baee5f6..0000000
--- a/tests/core/libcore/libcore/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.libcore
-# Note that we're not pulling in junit4 here because it's provided by
-# android.test.runner (which might pull in a different version from the
-# one that would be pulled in here).
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests mockito-target-minus-junit4
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/libcore/AndroidManifest.xml b/tests/core/libcore/libcore/AndroidManifest.xml
deleted file mode 100644
index 67a3023..0000000
--- a/tests/core/libcore/libcore/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.libcore">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/okhttp/Android.mk b/tests/core/libcore/okhttp/Android.mk
deleted file mode 100644
index c2b71c0..0000000
--- a/tests/core/libcore/okhttp/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.okhttp
-LOCAL_STATIC_JAVA_LIBRARIES := okhttp-nojarjar bouncycastle-nojarjar okhttp-tests-nojarjar
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/okhttp/AndroidManifest.xml b/tests/core/libcore/okhttp/AndroidManifest.xml
deleted file mode 100644
index f69bc83..0000000
--- a/tests/core/libcore/okhttp/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.okhttp">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/org/Android.mk b/tests/core/libcore/org/Android.mk
deleted file mode 100644
index 0f3f0ca..0000000
--- a/tests/core/libcore/org/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.org
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/org/AndroidManifest.xml b/tests/core/libcore/org/AndroidManifest.xml
deleted file mode 100644
index d705f65..0000000
--- a/tests/core/libcore/org/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.org">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/sun/Android.mk b/tests/core/libcore/sun/Android.mk
deleted file mode 100644
index ed6d2c7..0000000
--- a/tests/core/libcore/sun/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.sun
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/sun/AndroidManifest.xml b/tests/core/libcore/sun/AndroidManifest.xml
deleted file mode 100644
index 9888af3..0000000
--- a/tests/core/libcore/sun/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.sun">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/tests/Android.mk b/tests/core/libcore/tests/Android.mk
deleted file mode 100644
index 1d00b06..0000000
--- a/tests/core/libcore/tests/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2009 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.tests
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests mockito-target-minus-junit4
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/tests/AndroidManifest.xml b/tests/core/libcore/tests/AndroidManifest.xml
deleted file mode 100644
index f7dab9c..0000000
--- a/tests/core/libcore/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.core.tests.libcore.package.tests">
- <uses-permission android:name="android.permission.INTERNET" />
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="android.core.tests.runner"
- android:label="cts framework tests">
- <meta-data android:name="listener"
- android:value="com.android.cts.runner.CtsTestRunListener" />
- </instrumentation>
-
-</manifest>
diff --git a/tests/core/libcore/tzdata/Android.mk b/tests/core/libcore/tzdata/Android.mk
deleted file mode 100644
index ecbd070..0000000
--- a/tests/core/libcore/tzdata/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# 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)
-
-ifeq ($(BUILD_CTSCORE_PACKAGE),)
- $(error BUILD_CTSCORE_PACKAGE must be defined)
-endif
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.tzdata
-LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update-tests
-include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/fragment/src/android/fragment/cts/FragmentTransitionTest.java b/tests/fragment/src/android/fragment/cts/FragmentTransitionTest.java
index 4904a49..5e66722 100644
--- a/tests/fragment/src/android/fragment/cts/FragmentTransitionTest.java
+++ b/tests/fragment/src/android/fragment/cts/FragmentTransitionTest.java
@@ -31,6 +31,7 @@
import android.cts.util.transition.TargetTracking;
import android.cts.util.transition.TrackingTransition;
import android.graphics.Rect;
+import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule;
@@ -659,6 +660,45 @@
}
}
+ // Test that invisible fragment views don't participate in transitions
+ @Test
+ public void invisibleNoTransitions() throws Throwable {
+ if (!mOptimize) {
+ return; // only optimized transitions can avoid interaction
+ }
+ // enter transition
+ TransitionFragment fragment = new InvisibleFragment();
+ fragment.setLayoutId(R.layout.scene1);
+ mFragmentManager.beginTransaction()
+ .setAllowOptimization(mOptimize)
+ .add(R.id.fragmentContainer, fragment)
+ .addToBackStack(null)
+ .commit();
+ FragmentTestUtil.waitForExecution(mActivityRule);
+ fragment.waitForNoTransition();
+ verifyNoOtherTransitions(fragment);
+
+ // exit transition
+ mFragmentManager.beginTransaction()
+ .setAllowOptimization(mOptimize)
+ .remove(fragment)
+ .addToBackStack(null)
+ .commit();
+
+ fragment.waitForNoTransition();
+ verifyNoOtherTransitions(fragment);
+
+ // reenter transition
+ FragmentTestUtil.popBackStackImmediate(mActivityRule);
+ fragment.waitForNoTransition();
+ verifyNoOtherTransitions(fragment);
+
+ // return transition
+ FragmentTestUtil.popBackStackImmediate(mActivityRule);
+ fragment.waitForNoTransition();
+ verifyNoOtherTransitions(fragment);
+ }
+
private TransitionFragment setupInitialFragment() throws Throwable {
TransitionFragment fragment1 = new TransitionFragment();
fragment1.setLayoutId(R.layout.scene1);
@@ -921,6 +961,13 @@
setSharedElementEnterTransition(sharedElementEnterTransition);
setSharedElementReturnTransition(sharedElementReturnTransition);
}
+ }
+ public static class InvisibleFragment extends TransitionFragment {
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ view.setVisibility(View.INVISIBLE);
+ super.onViewCreated(view, savedInstanceState);
+ }
}
}
diff --git a/tests/fragment/src/android/fragment/cts/FragmentViewTests.java b/tests/fragment/src/android/fragment/cts/FragmentViewTests.java
index 1599307..82890df 100644
--- a/tests/fragment/src/android/fragment/cts/FragmentViewTests.java
+++ b/tests/fragment/src/android/fragment/cts/FragmentViewTests.java
@@ -24,6 +24,7 @@
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.Instrumentation;
+import android.os.Bundle;
import android.os.Debug;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
@@ -870,6 +871,34 @@
assertNotNull(findViewById(R.id.textC));
}
+ // Test that adding a fragment with invisible or gone views does not end up with the view
+ // being visible
+ @Test
+ public void addInvisibleAndGoneFragments() throws Throwable {
+ FragmentTestUtil.setContentView(mActivityRule, R.layout.simple_container);
+ ViewGroup container = (ViewGroup)
+ mActivityRule.getActivity().findViewById(R.id.fragmentContainer);
+ final FragmentManager fm = mActivityRule.getActivity().getFragmentManager();
+
+ final StrictViewFragment fragment1 = new InvisibleFragment();
+ fm.beginTransaction().add(R.id.fragmentContainer, fragment1).addToBackStack(null).commit();
+ FragmentTestUtil.executePendingTransactions(mActivityRule);
+ FragmentTestUtil.assertChildren(container, fragment1);
+
+ assertEquals(View.INVISIBLE, fragment1.getView().getVisibility());
+
+ final InvisibleFragment fragment2 = new InvisibleFragment();
+ fragment2.visibility = View.GONE;
+ fm.beginTransaction()
+ .replace(R.id.fragmentContainer, fragment2)
+ .addToBackStack(null)
+ .commit();
+ FragmentTestUtil.executePendingTransactions(mActivityRule);
+ FragmentTestUtil.assertChildren(container, fragment2);
+
+ assertEquals(View.GONE, fragment2.getView().getVisibility());
+ }
+
private View findViewById(int viewId) {
return mActivityRule.getActivity().findViewById(viewId);
}
@@ -883,4 +912,13 @@
fragments[i].getView());
}
}
-}
+
+ public static class InvisibleFragment extends StrictViewFragment {
+ public int visibility = View.INVISIBLE;
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ view.setVisibility(visibility);
+ super.onViewCreated(view, savedInstanceState);
+ }
+ }}
diff --git a/tests/libcore/javautilcollections/Android.mk b/tests/libcore/javautilcollections/Android.mk
new file mode 100644
index 0000000..2c7b7b1
--- /dev/null
+++ b/tests/libcore/javautilcollections/Android.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2016 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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_PREBUILT_STATIC_JAVA_LIBRARIES := \
+ guava-20.0-prebuilt:libs/guava-20.0.jar \
+ guava-testlib-20.0-prebuilt:libs/guava-testlib-20.0.jar
+include $(BUILD_MULTI_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_TAGS := tests
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctstestrunner \
+ guava-20.0-prebuilt \
+ guava-testlib-20.0-prebuilt
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_PACKAGE_NAME := CtsLibcoreJavaUtilCollectionsTestCases
+LOCAL_COMPATIBILITY_SUITE := cts
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/libcore/javautilcollections/AndroidManifest.xml b/tests/libcore/javautilcollections/AndroidManifest.xml
new file mode 100644
index 0000000..a7e8cee
--- /dev/null
+++ b/tests/libcore/javautilcollections/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2016 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="libcore.java.util.collectiontests">
+
+ <!-- AndroidJUnitRunner needs a largeHeap to collect the ~ 240k test methods to run. -->
+ <application android:largeHeap="true">
+ <uses-library android:name="android.test.runner"/>
+ </application>
+
+ <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="libcore.java.util.collectiontests"
+ android:label="Tests for Collection implementations in java.util">
+ </instrumentation>
+
+</manifest>
+
diff --git a/tests/libcore/javautilcollections/AndroidTest.xml b/tests/libcore/javautilcollections/AndroidTest.xml
new file mode 100644
index 0000000..7261c80
--- /dev/null
+++ b/tests/libcore/javautilcollections/AndroidTest.xml
@@ -0,0 +1,69 @@
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Config for CTS Libcore java.util Collection test cases">
+ <target_preparer class="com.android.compatibility.common.tradefed.targetprep.ApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="CtsLibcoreJavaUtilCollectionsTestCases.apk" />
+ </target_preparer>
+ <!--
+ Notes as of November 2016:
+
+ 1.) When the runner collects the set of tests to run, it
+ (a) attempts to directly run TestCase subclasses from guava-testlib, which they don't support,
+ (b) doesn't find classes with suite() methods.
+ (c) runs out of memory if attempting to run all of the > 220k tests in a single go
+ Breaking the tests down into chunks of ~ 40-50k tests each, and explicitly specifying the
+ suites to run, solves these problems.
+
+ 2.) Due to http://b/33068110 the classes with the suite() methods (in the "suite" sub-package)
+ need to extend TestSuite, which means that they need to delegate to separate classes (in the
+ "tests" sub-package) that extend classes from guava-testlib.
+ -->
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="libcore.java.util.collectiontests" />
+ <option name="class" value="libcore.java.util.suite.ConcurrentSkipListMapNaturalSuite" />
+ <option name="runtime-hint" value="10m" />
+ <option name="test-timeout" value="1200000" />
+ <option name="shell-timeout" value="1400000" />
+ </test>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="libcore.java.util.collectiontests" />
+ <option name="class" value="libcore.java.util.suite.ConcurrentSkipListMapWithComparatorSuite" />
+ <option name="runtime-hint" value="10m" />
+ <option name="test-timeout" value="1200000" />
+ <option name="shell-timeout" value="1400000" />
+ </test>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="libcore.java.util.collectiontests" />
+ <option name="class" value="libcore.java.util.suite.TreeMapNaturalSuite" />
+ <option name="runtime-hint" value="10m" />
+ <option name="test-timeout" value="1200000" />
+ <option name="shell-timeout" value="1400000" />
+ </test>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="libcore.java.util.collectiontests" />
+ <option name="class" value="libcore.java.util.suite.TreeMapWithComparatorSuite" />
+ <option name="runtime-hint" value="10m" />
+ <option name="test-timeout" value="1200000" />
+ <option name="shell-timeout" value="1400000" />
+ </test>
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="libcore.java.util.collectiontests" />
+ <option name="class" value="libcore.java.util.suite.OtherCollectionsSuite" />
+ <option name="runtime-hint" value="8m" />
+ <option name="test-timeout" value="1200000" />
+ <option name="shell-timeout" value="1400000" />
+ </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/libcore/javautilcollections/libs/guava-20.0.jar b/tests/libcore/javautilcollections/libs/guava-20.0.jar
new file mode 100644
index 0000000..632772f
--- /dev/null
+++ b/tests/libcore/javautilcollections/libs/guava-20.0.jar
Binary files differ
diff --git a/tests/libcore/javautilcollections/libs/guava-testlib-20.0.jar b/tests/libcore/javautilcollections/libs/guava-testlib-20.0.jar
new file mode 100644
index 0000000..6dd8d90
--- /dev/null
+++ b/tests/libcore/javautilcollections/libs/guava-testlib-20.0.jar
Binary files differ
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapNaturalSuite.java b/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapNaturalSuite.java
new file mode 100644
index 0000000..332190b
--- /dev/null
+++ b/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapNaturalSuite.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 libcore.java.util.suite;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil;
+import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil.MapsToTest;
+
+public class ConcurrentSkipListMapNaturalSuite extends TestSuite {
+ public static Test suite() {
+ return new AndroidTestsForMapsInJavaUtil(MapsToTest.CONCURRENT_SKIP_LIST_MAP_NATURAL)
+ .allTests();
+ }
+}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapWithComparatorSuite.java b/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapWithComparatorSuite.java
new file mode 100644
index 0000000..878e721
--- /dev/null
+++ b/tests/libcore/javautilcollections/src/libcore/java/util/suite/ConcurrentSkipListMapWithComparatorSuite.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 libcore.java.util.suite;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil;
+import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil.MapsToTest;
+
+public class ConcurrentSkipListMapWithComparatorSuite extends TestSuite {
+ public static Test suite() {
+ return new AndroidTestsForMapsInJavaUtil(
+ MapsToTest.CONCURRENT_SKIP_LIST_MAP_WITH_COMPARATOR).allTests();
+ }
+
+}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/suite/OtherCollectionsSuite.java b/tests/libcore/javautilcollections/src/libcore/java/util/suite/OtherCollectionsSuite.java
new file mode 100644
index 0000000..6af45f4
--- /dev/null
+++ b/tests/libcore/javautilcollections/src/libcore/java/util/suite/OtherCollectionsSuite.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 libcore.java.util.suite;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import libcore.java.util.tests.AndroidTestsForListsInJavaUtil;
+import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil;
+import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil.MapsToTest;
+import libcore.java.util.tests.AndroidTestsForQueuesInJavaUtil;
+import libcore.java.util.tests.AndroidTestsForSetsInJavaUtil;
+
+/**
+ * A suite of all guava-testlib Collection tests not covered by the other suites in this
+ * package.
+ */
+public class OtherCollectionsSuite extends TestSuite {
+ public static Test suite() {
+ TestSuite result = new TestSuite();
+ result.addTest(new AndroidTestsForListsInJavaUtil().allTests());
+ result.addTest(new AndroidTestsForMapsInJavaUtil(MapsToTest.OTHER).allTests());
+ result.addTest(new AndroidTestsForQueuesInJavaUtil().allTests());
+ result.addTest(new AndroidTestsForSetsInJavaUtil().allTests());
+ return result;
+ }
+}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapNaturalSuite.java b/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapNaturalSuite.java
new file mode 100644
index 0000000..68a7624
--- /dev/null
+++ b/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapNaturalSuite.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 libcore.java.util.suite;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil;
+import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil.MapsToTest;
+
+public class TreeMapNaturalSuite extends TestSuite {
+ public static Test suite() {
+ return new AndroidTestsForMapsInJavaUtil(MapsToTest.TREE_MAP_NATURAL).allTests();
+ }
+}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapWithComparatorSuite.java b/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapWithComparatorSuite.java
new file mode 100644
index 0000000..6e6fd6f
--- /dev/null
+++ b/tests/libcore/javautilcollections/src/libcore/java/util/suite/TreeMapWithComparatorSuite.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 libcore.java.util.suite;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil;
+import libcore.java.util.tests.AndroidTestsForMapsInJavaUtil.MapsToTest;
+
+public class TreeMapWithComparatorSuite extends TestSuite {
+ public static Test suite() {
+ return new AndroidTestsForMapsInJavaUtil(MapsToTest.TREE_MAP_WITH_COMPARATOR).allTests();
+ }
+}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForListsInJavaUtil.java b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForListsInJavaUtil.java
new file mode 100644
index 0000000..8d9177c
--- /dev/null
+++ b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForListsInJavaUtil.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 libcore.java.util.tests;
+
+import com.google.common.collect.testing.TestsForListsInJavaUtil;
+import com.google.common.collect.testing.testers.CollectionToArrayTester;
+
+import junit.framework.Test;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * Guava-testlib tests for {@code List} implementations from {@code java.util}.
+ */
+public class AndroidTestsForListsInJavaUtil extends TestsForListsInJavaUtil {
+ @Override
+ protected Collection<Method> suppressForArraysAsList() {
+ return Collections.singleton(
+ // http://b/30829421
+ CollectionToArrayTester.getToArrayIsPlainObjectArrayMethod());
+ }
+}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForMapsInJavaUtil.java b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForMapsInJavaUtil.java
new file mode 100644
index 0000000..8a685d9
--- /dev/null
+++ b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForMapsInJavaUtil.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 libcore.java.util.tests;
+
+import com.google.common.collect.testing.TestsForMapsInJavaUtil;
+import com.google.common.collect.testing.testers.CollectionAddAllTester;
+import com.google.common.collect.testing.testers.CollectionAddTester;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
+
+/**
+ * Guava-testlib tests for {@link MapsToTest} that were specified as a
+ * constructor argument.
+ */
+public class AndroidTestsForMapsInJavaUtil extends TestsForMapsInJavaUtil {
+ public enum MapsToTest {
+ /** All Maps other than those below. */
+ OTHER,
+ /** TreeMao with natural ordering. */
+ TREE_MAP_NATURAL,
+ /** TreeMap with a Comparator. */
+ TREE_MAP_WITH_COMPARATOR,
+ /** ConcurrentSKipListMap with natural ordering. */
+ CONCURRENT_SKIP_LIST_MAP_NATURAL,
+ /** ConcurrentSKipListMap with a Comparator. */
+ CONCURRENT_SKIP_LIST_MAP_WITH_COMPARATOR
+ }
+
+ private final MapsToTest mapsToTest;
+
+ public AndroidTestsForMapsInJavaUtil(MapsToTest mapsToTest) {
+ this.mapsToTest = Objects.requireNonNull(mapsToTest);
+ }
+
+ /**
+ * Returns the tests for the {@link MapsToTest} from {@code java.util}.
+ */
+ @Override
+ public final Test allTests() {
+ TestSuite suite = new TestSuite("java.util Maps: " + mapsToTest);
+ switch (mapsToTest) {
+ case OTHER:
+ suite.addTest(testsForEmptyMap());
+ suite.addTest(testsForSingletonMap());
+ suite.addTest(testsForHashMap());
+ suite.addTest(testsForLinkedHashMap());
+ suite.addTest(testsForEnumMap());
+ suite.addTest(testsForConcurrentHashMap());
+ break;
+ case TREE_MAP_NATURAL:
+ suite.addTest(testsForTreeMapNatural());
+ break;
+ case TREE_MAP_WITH_COMPARATOR:
+ suite.addTest(testsForTreeMapWithComparator());
+ break;
+ case CONCURRENT_SKIP_LIST_MAP_NATURAL:
+ suite.addTest(testsForConcurrentSkipListMapNatural());
+ break;
+ case CONCURRENT_SKIP_LIST_MAP_WITH_COMPARATOR:
+ suite.addTest(testsForConcurrentSkipListMapWithComparator());
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown part: " + mapsToTest);
+ }
+ return suite;
+ }
+
+ @Override
+ protected final Collection<Method> suppressForConcurrentHashMap() {
+ // http://b/30853241
+ return Arrays.asList(
+ CollectionAddAllTester.getAddAllUnsupportedNonePresentMethod(),
+ CollectionAddAllTester.getAddAllUnsupportedSomePresentMethod(),
+ CollectionAddTester.getAddUnsupportedNotPresentMethod());
+ }
+}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForQueuesInJavaUtil.java b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForQueuesInJavaUtil.java
new file mode 100644
index 0000000..e3dcd62
--- /dev/null
+++ b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForQueuesInJavaUtil.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 libcore.java.util.tests;
+
+import com.google.common.collect.testing.TestsForQueuesInJavaUtil;
+
+import junit.framework.Test;
+
+/**
+ * Guava-testlib tests for {@code Queue} implementations from {@code java.util}.
+ */
+public class AndroidTestsForQueuesInJavaUtil extends TestsForQueuesInJavaUtil {
+}
diff --git a/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForSetsInJavaUtil.java b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForSetsInJavaUtil.java
new file mode 100644
index 0000000..c4e41f4
--- /dev/null
+++ b/tests/libcore/javautilcollections/src/libcore/java/util/tests/AndroidTestsForSetsInJavaUtil.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 libcore.java.util.tests;
+
+import com.google.common.collect.testing.TestsForSetsInJavaUtil;
+
+import junit.framework.Test;
+
+/**
+ * Guava-testlib tests for {@code Set} implementations from {@code java.util}.
+ */
+public class AndroidTestsForSetsInJavaUtil extends TestsForSetsInJavaUtil {
+}
diff --git a/tests/libcore/ojluni/Android.mk b/tests/libcore/ojluni/Android.mk
index c2ba33b..36ba4f2 100644
--- a/tests/libcore/ojluni/Android.mk
+++ b/tests/libcore/ojluni/Android.mk
@@ -39,8 +39,6 @@
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
LOCAL_JAVA_RESOURCE_FILES := \
libcore/expectations/brokentests.txt \
libcore/expectations/icebox.txt \
diff --git a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
index e22d560..698189a 100644
--- a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
+++ b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
@@ -690,19 +690,18 @@
public void testAccountRenameAndGetPreviousName()
throws OperationCanceledException, AuthenticatorException, IOException {
// Add a first account
- boolean result = am.addAccountExplicitly(ACCOUNT,
- ACCOUNT_PASSWORD,
- USERDATA_BUNDLE);
+
+ boolean result = am.addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, USERDATA_BUNDLE);
+
assertTrue(result);
- // Prior to a renmae, the previous name should be null.
+ // Prior to a rename, the previous name should be null.
String nullName = am.getPreviousName(ACCOUNT);
assertNull(nullName);
final int expectedAccountsCount = getAccountsCount();
Account renamedAccount = renameAccount(am, ACCOUNT, ACCOUNT_NEW_NAME);
-
/*
* Make sure that the resultant renamed account has the correct name
* and is associated with the correct account type.
@@ -725,9 +724,10 @@
assertEquals(ACCOUNT.name, am.getPreviousName(renamedAccount));
- // Need to clean up
+ // Need to clean up
assertTrue(removeAccount(am, renamedAccount, mActivity, null /* callback */).getBoolean(
AccountManager.KEY_BOOLEAN_RESULT));
+
}
/**
@@ -978,34 +978,10 @@
/*
* Test registration of visibility and then test subsequent visibility checks:
- * Test removeVisibility, makeVisible, isVisible. Note that if no mappings
- * exist, defaults to visible due to nature of addAccountExplicitly currently!
*/
- public void testRegisterVisibility() throws IOException,
- AuthenticatorException, OperationCanceledException {
- int uid1 = 12345;
- int uid2 = 54321;
- /* notable case, notice that a is visible even though it hasn't been added to a white list,
- this is because there is no whitelist created and the assumption for no whitelist
- is visibility.*/
- assertTrue(am.isAccountVisible(ACCOUNT, uid1));
- assertTrue(am.makeAccountVisible(ACCOUNT, uid2));
- assertFalse(am.makeAccountVisible(ACCOUNT, uid2));
- /* now that there is a whitelist for the account a, uid1 registers as false,
- whitelist is created through addAccountExplicitlyWithUid */
- assertFalse(am.isAccountVisible(ACCOUNT, uid1));
- assertTrue(am.makeAccountVisible(ACCOUNT, uid1));
- assertTrue(am.isAccountVisible(ACCOUNT, uid1));
- assertTrue(am.removeAccountVisibility(ACCOUNT, uid2));
- assertFalse(am.isAccountVisible(ACCOUNT, uid2));
- assertTrue(am.removeAccountVisibility(ACCOUNT, uid1));
- /* notice how even though account has a white list of size 0, white list functionality
- NOT removed, this functionality is only removed through a call to "addAccountsExplicitly",
- which allows account to be accessed by ALL uids, so removes white listed settings. */
- assertFalse(am.removeAccountVisibility(ACCOUNT, uid2));
- assertFalse(am.removeAccountVisibility(ACCOUNT, uid2));
-
- //clears whitelist by adding account explicitly and then removing account
+ public void testRegisterVisibility()
+ throws IOException, AuthenticatorException, OperationCanceledException {
+ // TODO test visibility
am.addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
removeAccount(am, ACCOUNT, mActivity, null /* callback */);
@@ -1014,24 +990,11 @@
/*
- * Test Positive Case for adding accounts explicitly with UID
+ * Test Case for adding accounts explicitly with visibility
*/
- public void testAddAccountExplicitlyWithUid() throws OperationCanceledException,
- AuthenticatorException, IOException{
- boolean result = am.addAccountExplicitly(
- ACCOUNT,
- ACCOUNT_PASSWORD,
- USERDATA_BUNDLE,
- new int[] {Binder.getCallingUid()});
- assertTrue(result);
- Account[] accounts = am.getAccounts();
- assertTrue(accounts.length == 1);
- assertTrue(accounts[0].equals(ACCOUNT));
- /* note that the authenticator and this class have same signature
- as well as it is in white list */
- assertTrue(am.isAccountVisible(ACCOUNT, Binder.getCallingUid()));
- assertTrue(removeAccount(am, ACCOUNT, mActivity, null /* callback */).getBoolean(
- AccountManager.KEY_BOOLEAN_RESULT));
+ public void testAddAccountExplicitlyWithVisibility()
+ throws OperationCanceledException, AuthenticatorException, IOException {
+ // TODO update tests
}
private static class BlockingGetAuthTokenFetcher implements TokenFetcher {
diff --git a/tests/tests/bionic/Android.build.copy.libs.mk b/tests/tests/bionic/Android.build.copy.libs.mk
index dd7d4e0..6c2d546 100644
--- a/tests/tests/bionic/Android.build.copy.libs.mk
+++ b/tests/tests/bionic/Android.build.copy.libs.mk
@@ -49,6 +49,7 @@
libtest_check_order_reloc_siblings_e.so \
libtest_check_order_reloc_siblings_f.so \
libtest_check_order_reloc_siblings.so \
+ libtest_check_rtld_next_from_library.so \
libtest_dlopen_from_ctor_main.so \
libtest_dlopen_from_ctor.so \
libtest_dlopen_weak_undefined_func.so \
diff --git a/tests/tests/drm/Android.mk b/tests/tests/drm/Android.mk
index 02567be..210be2c 100644
--- a/tests/tests/drm/Android.mk
+++ b/tests/tests/drm/Android.mk
@@ -24,7 +24,7 @@
# and when built explicitly put it in the data partition
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctsdeviceutil
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/drm/res/raw/testmp3_2.mp3 b/tests/tests/drm/res/raw/testmp3_2.mp3
new file mode 100644
index 0000000..6a70c69
--- /dev/null
+++ b/tests/tests/drm/res/raw/testmp3_2.mp3
Binary files differ
diff --git a/tests/tests/drm/src/android/drm/cts/DRMTest.java b/tests/tests/drm/src/android/drm/cts/DRMTest.java
index bb77668..190d782 100644
--- a/tests/tests/drm/src/android/drm/cts/DRMTest.java
+++ b/tests/tests/drm/src/android/drm/cts/DRMTest.java
@@ -18,13 +18,27 @@
import android.content.ContentValues;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.cts.util.MediaUtils;
import android.test.AndroidTestCase;
import android.util.Log;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.io.SequenceInputStream;
+import java.nio.charset.StandardCharsets;
+import java.io.ByteArrayInputStream;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
import java.util.Iterator;
+import java.util.Vector;
import android.drm.DrmManagerClient;
import android.drm.DrmConvertedStatus;
@@ -35,6 +49,11 @@
import android.drm.DrmRights;
import android.drm.DrmStore;
import android.drm.DrmUtils;
+import android.media.MediaExtractor;
+import android.media.MediaMetadataRetriever;
+import android.media.MediaPlayer;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemClock;
public class DRMTest extends AndroidTestCase {
private static String TAG = "CtsDRMTest";
@@ -197,6 +216,90 @@
}
}
+ public void testForwardLockAccess() throws Exception {
+ DrmManagerClient drmManager= new DrmManagerClient(mContext);
+ String[] engines = drmManager.getAvailableDrmEngines();
+ boolean haveForwardLock = false;
+ for (String engine: engines) {
+ if (engine.equals("OMA V1 Forward Lock")) {
+ haveForwardLock = true;
+ }
+ }
+ drmManager.close();
+ if (!haveForwardLock) {
+ Log.i(TAG, "Skipping forward lock test because forward lock is not available");
+ return;
+ }
+
+ Vector<InputStream> sequence = new Vector<InputStream>();
+
+ String dmHeader = "--mime_content_boundary\r\n" +
+ "Content-Type: audio/mpeg\r\n" +
+ "Content-Transfer-Encoding: binary\r\n\r\n";
+ sequence.add(new ByteArrayInputStream(dmHeader.getBytes(StandardCharsets.UTF_8)));
+
+ AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(R.raw.testmp3_2);
+ FileInputStream body = afd.createInputStream();
+ sequence.add(body);
+
+ String dmFooter = "\r\n--mime_content_boundary--";
+ sequence.add(new ByteArrayInputStream(dmFooter.getBytes(StandardCharsets.UTF_8)));
+
+ SequenceInputStream dmStream = new SequenceInputStream(sequence.elements());
+ String flPath = mContext.getExternalCacheDir() + "/temp.fl";
+ RandomAccessFile flFile = new RandomAccessFile(flPath, "rw");
+ assertTrue("couldn't convert to fl file",
+ MediaUtils.convertDmToFl(mContext, dmStream, flFile));
+ dmStream.close(); // this closes the underlying streams and AFD as well
+ flFile.close();
+
+ ParcelFileDescriptor flFd = null;
+ try {
+ // check that the .fl file can be played
+ MediaPlayer player = new MediaPlayer();
+ try {
+ flFd = ParcelFileDescriptor.open(
+ new File(flPath), ParcelFileDescriptor.MODE_READ_ONLY);
+ player.setDataSource(flFd.getFileDescriptor(), 0, flFd.getStatSize());
+ player.prepare();
+ player.start();
+ SystemClock.sleep(2000);
+ assertTrue("player is not playing", player.isPlaying());
+ player.release();
+ } catch (Exception e) {
+ Log.d(TAG, "MediaPlayer playback failed:", e);
+ } finally {
+ player.release();
+ }
+
+ // check that the .fl file can be parsed with MediaMetadataRetriever
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ try {
+ retriever.setDataSource(flFd.getFileDescriptor());
+ String numTracks =
+ retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS);
+ assertEquals("wrong number of tracks found in file", "1", numTracks);
+ } finally {
+ retriever.release();
+ }
+
+ // check that the .fl file cannot be opened with MediaExtractor
+ MediaExtractor ex = new MediaExtractor();
+ try {
+ ex.setDataSource(flFd.getFileDescriptor());
+ int n = ex.getTrackCount();
+ fail("extractor creation should have failed, but found " + n + " tracks");
+ } catch (Exception e) {
+ // ignore, expected to fail
+ } finally {
+ ex.release();
+ }
+ } finally {
+ flFd.close();
+ new File(flPath).delete();
+ }
+ }
+
private class OnEventListenerImpl implements DrmManagerClient.OnEventListener {
private Config mConfig;
public OnEventListenerImpl(Config config) {
diff --git a/tests/tests/graphics/src/android/graphics/cts/Bitmap_ConfigTest.java b/tests/tests/graphics/src/android/graphics/cts/Bitmap_ConfigTest.java
index c9aba5d..ebb7d6a 100644
--- a/tests/tests/graphics/src/android/graphics/cts/Bitmap_ConfigTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/Bitmap_ConfigTest.java
@@ -42,12 +42,11 @@
public void testValues(){
Config[] config = Config.values();
- assertTrue(config.length >= 5);
+ assertTrue(config.length >= 4);
assertEquals(Config.ALPHA_8, config[0]);
assertEquals(Config.RGB_565, config[1]);
assertEquals(Config.ARGB_4444, config[2]);
assertEquals(Config.ARGB_8888, config[3]);
- assertEquals(Config.HARDWARE, config[4]);
//Config is used as a argument here for all the methods that use it
assertNotNull(Bitmap.createBitmap(10, 24, Config.ALPHA_8));
diff --git a/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java b/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java
index 41dc97d..4494656 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ColorSpaceTest.java
@@ -15,6 +15,7 @@
*/
package android.graphics.cts;
+import android.graphics.Bitmap;
import android.graphics.ColorSpace;
import android.support.test.filters.SmallTest;
@@ -175,9 +176,9 @@
m2 = cs.getMinValue(1);
m3 = cs.getMinValue(2);
- assertEquals(0.0f, m1, 1e-9f);
- assertEquals(0.0f, m2, 1e-9f);
- assertEquals(0.0f, m3, 1e-9f);
+ assertEquals(-2.0f, m1, 1e-9f);
+ assertEquals(-2.0f, m2, 1e-9f);
+ assertEquals(-2.0f, m3, 1e-9f);
m1 = cs.getMaxValue(0);
m2 = cs.getMaxValue(1);
@@ -723,6 +724,35 @@
});
}
+ @Test
+ public void testRendererSize() {
+ Bitmap b = ColorSpace.createRenderer()
+ .size(0)
+ .render();
+ assertEquals(128, b.getWidth());
+ assertEquals(128, b.getHeight());
+
+ b = ColorSpace.createRenderer()
+ .size(768)
+ .render();
+ assertEquals(768, b.getWidth());
+ assertEquals(768, b.getHeight());
+ }
+
+ @Test
+ public void testRenderer() {
+ Bitmap b = ColorSpace.createRenderer()
+ .size(1024)
+ .clip(true)
+ .showWhitePoint(false)
+ .add(ColorSpace.get(ColorSpace.Named.SRGB), 0xffffffff)
+ .add(ColorSpace.get(ColorSpace.Named.DCI_P3), 0xffffffff)
+ .add(ColorSpace.get(ColorSpace.Named.PRO_PHOTO_RGB), 0.1f, 0.5f, 0.1f, 0xff000000)
+ .add(ColorSpace.get(ColorSpace.Named.ADOBE_RGB), 0.1f, 0.5f, 0.1f, 0xff000000)
+ .render();
+ assertNotNull(b);
+ }
+
@SuppressWarnings("SameParameterValue")
private static void assertArrayNotEquals(float[] a, float[] b, float eps) {
for (int i = 0; i < a.length; i++) {
diff --git a/tests/tests/graphics/src/android/opengl/cts/ByteBufferTest.java b/tests/tests/graphics/src/android/opengl/cts/ByteBufferTest.java
new file mode 100644
index 0000000..8d596b4
--- /dev/null
+++ b/tests/tests/graphics/src/android/opengl/cts/ByteBufferTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl.cts;
+
+import android.support.test.filters.SmallTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+
+import static android.opengl.GLES30.GL_BUFFER_MAP_POINTER;
+import static android.opengl.GLES30.GL_DYNAMIC_READ;
+import static android.opengl.GLES30.GL_MAP_READ_BIT;
+import static android.opengl.GLES30.GL_UNIFORM_BUFFER;
+import static android.opengl.GLES30.glBindBuffer;
+import static android.opengl.GLES30.glBufferData;
+import static android.opengl.GLES30.glDeleteBuffers;
+import static android.opengl.GLES30.glGenBuffers;
+import static android.opengl.GLES30.glGetBufferPointerv;
+import static android.opengl.GLES30.glMapBufferRange;
+import static android.opengl.GLES30.glUnmapBuffer;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for functions that return a ByteBuffer.
+ */
+@SmallTest
+@RunWith(BlockJUnit4ClassRunner.class) // DO NOT USE AndroidJUnit4, it messes up threading
+public class ByteBufferTest extends GlTestBase {
+ @Test
+ public void testMapBufferRange() {
+ // Always pass on ES 2.0
+ if (Egl14Utils.getMajorVersion() >= 3) {
+ int[] buffer = new int[1];
+ glGenBuffers(1, buffer, 0);
+ glBindBuffer(GL_UNIFORM_BUFFER, buffer[0]);
+ glBufferData(GL_UNIFORM_BUFFER, 1024, null, GL_DYNAMIC_READ);
+
+ Buffer mappedBuffer = glMapBufferRange(GL_UNIFORM_BUFFER, 0, 1024, GL_MAP_READ_BIT);
+
+ assertNotNull(mappedBuffer);
+ assertTrue(mappedBuffer instanceof ByteBuffer);
+
+ Buffer pointerBuffer = glGetBufferPointerv(GL_UNIFORM_BUFFER, GL_BUFFER_MAP_POINTER);
+ assertNotNull(pointerBuffer);
+ assertTrue(pointerBuffer instanceof ByteBuffer);
+
+ glUnmapBuffer(GL_UNIFORM_BUFFER);
+
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ glDeleteBuffers(1, buffer, 0);
+ }
+ }
+}
diff --git a/tests/tests/graphics/src/android/opengl/cts/Egl10Utils.java b/tests/tests/graphics/src/android/opengl/cts/Egl10Utils.java
new file mode 100644
index 0000000..83aa158
--- /dev/null
+++ b/tests/tests/graphics/src/android/opengl/cts/Egl10Utils.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl.cts;
+
+import android.opengl.EGL14;
+import android.opengl.EGLExt;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLDisplay;
+
+final class Egl10Utils {
+ private Egl10Utils() {
+ }
+
+ static EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, int[] configSpec) {
+ int[] value = new int[1];
+ if (!egl.eglChooseConfig(display, configSpec, null, 0,
+ value)) {
+ throw new IllegalArgumentException("eglChooseConfig failed");
+ }
+
+ int numConfigs = value[0];
+ if (numConfigs <= 0) {
+ throw new IllegalArgumentException("No configs match configSpec");
+ }
+
+ EGLConfig[] configs = new EGLConfig[numConfigs];
+ if (!egl.eglChooseConfig(display, configSpec, configs, numConfigs, value)) {
+ throw new IllegalArgumentException("eglChooseConfig#2 failed");
+ }
+ EGLConfig config = chooseConfig(egl, display, configs, configSpec);
+ if (config == null) {
+ throw new IllegalArgumentException("No config chosen");
+ }
+ return config;
+ }
+
+ static int[] filterConfigSpec(int[] configSpec, int version) {
+ if (version != 2 && version != 3) {
+ return configSpec;
+ }
+
+ int len = configSpec.length;
+ int[] newConfigSpec = new int[len + 2];
+ System.arraycopy(configSpec, 0, newConfigSpec, 0, len-1);
+
+ newConfigSpec[len-1] = EGL10.EGL_RENDERABLE_TYPE;
+ if (version == 2) {
+ newConfigSpec[len] = EGL14.EGL_OPENGL_ES2_BIT; /* EGL_OPENGL_ES2_BIT */
+ } else {
+ newConfigSpec[len] = EGLExt.EGL_OPENGL_ES3_BIT_KHR; /* EGL_OPENGL_ES3_BIT_KHR */
+ }
+ newConfigSpec[len + 1] = EGL10.EGL_NONE;
+
+ return newConfigSpec;
+ }
+
+ private static EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
+ EGLConfig[] configs, int[] configSpec) {
+
+ int redSize = findValue(configSpec, EGL10.EGL_RED_SIZE);
+ int greenSize = findValue(configSpec, EGL10.EGL_GREEN_SIZE);
+ int blueSize = findValue(configSpec, EGL10.EGL_BLUE_SIZE);
+ int alphaSize = findValue(configSpec, EGL10.EGL_ALPHA_SIZE);
+ int depthSize = findValue(configSpec, EGL10.EGL_DEPTH_SIZE);
+ int stencilSize = findValue(configSpec, EGL10.EGL_STENCIL_SIZE);
+
+ for (EGLConfig config : configs) {
+ int d = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE);
+ int s = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE);
+ if ((d >= depthSize) && (s >= stencilSize)) {
+ int r = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE);
+ int g = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE);
+ int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE);
+ int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE);
+ if ((r == redSize) && (g == greenSize) && (b == blueSize) && (a == alphaSize)) {
+ return config;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static int findValue(int[] configSpec, int name) {
+ for (int i = 0; i < configSpec.length; i += 2) {
+ if (configSpec[i] == name) {
+ return configSpec[i + 1];
+ }
+ }
+ return 0;
+ }
+
+ private static int findConfigAttrib(EGL10 egl, EGLDisplay display,
+ EGLConfig config, int attribute) {
+ int[] value = new int[1];
+ if (egl.eglGetConfigAttrib(display, config, attribute, value)) {
+ return value[0];
+ }
+ return 0;
+ }
+}
diff --git a/tests/tests/graphics/src/android/opengl/cts/Egl14Utils.java b/tests/tests/graphics/src/android/opengl/cts/Egl14Utils.java
new file mode 100644
index 0000000..677accc
--- /dev/null
+++ b/tests/tests/graphics/src/android/opengl/cts/Egl14Utils.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl.cts;
+
+import android.opengl.EGL14;
+import android.opengl.EGLConfig;
+import android.opengl.EGLContext;
+import android.opengl.EGLDisplay;
+import android.opengl.EGLExt;
+import android.opengl.EGLSurface;
+import android.opengl.GLES20;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Utilities to test EGL APIs.
+ */
+final class Egl14Utils {
+ private Egl14Utils() {
+ }
+
+ static int getMajorVersion() {
+ // Section 6.1.5 of the OpenGL ES specification indicates the GL version
+ // string strictly follows this format:
+ //
+ // OpenGL<space>ES<space><version number><space><vendor-specific information>
+ //
+ // In addition section 6.1.5 describes the version number thusly:
+ //
+ // "The version number is either of the form major number.minor number or
+ // major number.minor number.release number, where the numbers all have one
+ // or more digits. The release number and vendor specific information are
+ // optional."
+ String version = GLES20.glGetString(GLES20.GL_VERSION);
+ Pattern pattern = Pattern.compile("OpenGL ES ([0-9]+)\\.([0-9]+)");
+ Matcher matcher = pattern.matcher(version);
+ if (matcher.find()) {
+ return Integer.parseInt(matcher.group(1));
+ }
+ return 2;
+ }
+
+ /**
+ * Returns an initialized default display.
+ */
+ static EGLDisplay createEglDisplay() {
+ EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
+ if (eglDisplay == EGL14.EGL_NO_DISPLAY) {
+ throw new IllegalStateException("no EGL display");
+ }
+
+ int[] major = new int[1];
+ int[] minor = new int[1];
+ if (!EGL14.eglInitialize(eglDisplay, major, 0, minor, 0)) {
+ throw new IllegalStateException("error in eglInitialize");
+ }
+
+ return eglDisplay;
+ }
+
+ /**
+ * Returns a new GL ES 2.0 context for the specified {@code eglDisplay}.
+ */
+ static EGLContext createEglContext(EGLDisplay eglDisplay) {
+ return createEglContext(eglDisplay, getEglConfig(eglDisplay, 2), 2);
+ }
+
+ /**
+ * Returns a new GL ES context for the specified display, config and version.
+ */
+ static EGLContext createEglContext(EGLDisplay eglDisplay, EGLConfig eglConfig, int version) {
+ int[] contextAttributes = { EGL14.EGL_CONTEXT_CLIENT_VERSION, version, EGL14.EGL_NONE };
+ return EGL14.eglCreateContext(eglDisplay, eglConfig,
+ EGL14.EGL_NO_CONTEXT, contextAttributes, 0);
+ }
+
+ /**
+ * Destroys the GL context identified by {@code eglDisplay} and {@code eglContext}.
+ */
+ static void destroyEglContext(EGLDisplay eglDisplay, EGLContext eglContext) {
+ EGL14.eglMakeCurrent(eglDisplay,
+ EGL14.EGL_NO_SURFACE,
+ EGL14.EGL_NO_SURFACE,
+ EGL14.EGL_NO_CONTEXT);
+ int error = EGL14.eglGetError();
+ if (error != EGL14.EGL_SUCCESS) {
+ throw new RuntimeException("error releasing context: " + error);
+ }
+
+ EGL14.eglDestroyContext(eglDisplay, eglContext);
+ error = EGL14.eglGetError();
+ if (error != EGL14.EGL_SUCCESS) {
+ throw new RuntimeException("error destroying context: " + error);
+ }
+ }
+
+ static void releaseAndTerminate(EGLDisplay eglDisplay) {
+ int error;
+ EGL14.eglReleaseThread();
+ error = EGL14.eglGetError();
+ if (error != EGL14.EGL_SUCCESS) {
+ throw new RuntimeException("error releasing thread: " + error);
+ }
+
+ EGL14.eglTerminate(eglDisplay);
+ error = EGL14.eglGetError();
+ if (error != EGL14.EGL_SUCCESS) {
+ throw new RuntimeException("error terminating display: " + error);
+ }
+ }
+
+ static EGLConfig getEglConfig(EGLDisplay eglDisplay, int version) {
+ // Get an EGLConfig.
+ int renderableType = EGL14.EGL_OPENGL_ES2_BIT;
+ if (version == 3) {
+ renderableType = EGLExt.EGL_OPENGL_ES3_BIT_KHR;
+ }
+ final int RED_SIZE = 8;
+ final int GREEN_SIZE = 8;
+ final int BLUE_SIZE = 8;
+ final int ALPHA_SIZE = 8;
+ final int DEPTH_SIZE = 0;
+ final int STENCIL_SIZE = 0;
+ final int[] DEFAULT_CONFIGURATION = new int[] {
+ EGL14.EGL_RENDERABLE_TYPE, renderableType,
+ EGL14.EGL_RED_SIZE, RED_SIZE,
+ EGL14.EGL_GREEN_SIZE, GREEN_SIZE,
+ EGL14.EGL_BLUE_SIZE, BLUE_SIZE,
+ EGL14.EGL_ALPHA_SIZE, ALPHA_SIZE,
+ EGL14.EGL_DEPTH_SIZE, DEPTH_SIZE,
+ EGL14.EGL_STENCIL_SIZE, STENCIL_SIZE,
+ EGL14.EGL_NONE};
+
+ int[] configsCount = new int[1];
+ EGLConfig[] eglConfigs = new EGLConfig[1];
+ if (!EGL14.eglChooseConfig(
+ eglDisplay, DEFAULT_CONFIGURATION, 0, eglConfigs, 0, 1, configsCount, 0)) {
+ throw new RuntimeException("eglChooseConfig failed");
+ }
+ return eglConfigs[0];
+ }
+
+ /**
+ * Checks for a GL error using {@link GLES20#glGetError()}.
+ *
+ * @throws RuntimeException if there is a GL error
+ */
+ static void checkGlError() {
+ int errorCode;
+ if ((errorCode = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+ throw new RuntimeException("gl error: " + Integer.toHexString(errorCode));
+ }
+ }
+}
diff --git a/tests/tests/graphics/src/android/opengl/cts/EglContextTest.java b/tests/tests/graphics/src/android/opengl/cts/EglContextTest.java
index ca64d28..3cfd2d5 100644
--- a/tests/tests/graphics/src/android/opengl/cts/EglContextTest.java
+++ b/tests/tests/graphics/src/android/opengl/cts/EglContextTest.java
@@ -17,10 +17,8 @@
package android.opengl.cts;
import android.opengl.EGL14;
-import android.opengl.EGLConfig;
import android.opengl.EGLContext;
import android.opengl.EGLDisplay;
-import android.opengl.GLES20;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -41,9 +39,10 @@
EGLDisplay eglDisplay = null;
EGLContext eglContext = null;
try {
- eglDisplay = createEglDisplay();
- eglContext = createEglContext(eglDisplay);
- destroyEglContext(eglDisplay, eglContext);
+ eglDisplay = Egl14Utils.createEglDisplay();
+ eglContext = Egl14Utils.createEglContext(eglDisplay);
+ Egl14Utils.destroyEglContext(eglDisplay, eglContext);
+ Egl14Utils.releaseAndTerminate(eglDisplay);
eglDisplay = null;
eglContext = null;
} finally {
@@ -56,108 +55,4 @@
}
}
}
-
- /**
- * Returns an initialized default display.
- */
- private static EGLDisplay createEglDisplay() {
- EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
- if (eglDisplay == EGL14.EGL_NO_DISPLAY) {
- throw new IllegalStateException("no EGL display");
- }
-
- int[] major = new int[1];
- int[] minor = new int[1];
- if (!EGL14.eglInitialize(eglDisplay, major, 0, minor, 0)) {
- throw new IllegalStateException("error in eglInitialize");
- }
- checkGlError();
-
- return eglDisplay;
- }
-
- /**
- * Returns a new GL context for the specified {@code eglDisplay}.
- */
- private static EGLContext createEglContext(EGLDisplay eglDisplay) {
- int[] contextAttributes = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE };
- EGLContext eglContext = EGL14.eglCreateContext(eglDisplay,
- getEglConfig(eglDisplay), EGL14.EGL_NO_CONTEXT, contextAttributes, 0);
- checkGlError();
-
- return eglContext;
- }
-
- /**
- * Destroys the GL context identifier by {@code eglDisplay} and {@code eglContext}.
- */
- private static void destroyEglContext(EGLDisplay eglDisplay, EGLContext eglContext) {
- EGL14.eglMakeCurrent(eglDisplay,
- EGL14.EGL_NO_SURFACE,
- EGL14.EGL_NO_SURFACE,
- EGL14.EGL_NO_CONTEXT);
- int error = EGL14.eglGetError();
- if (error != EGL14.EGL_SUCCESS) {
- throw new RuntimeException("error releasing context: " + error);
- }
-
- EGL14.eglDestroyContext(eglDisplay, eglContext);
- error = EGL14.eglGetError();
- if (error != EGL14.EGL_SUCCESS) {
- throw new RuntimeException("error destroying context: " + error);
- }
-
- EGL14.eglReleaseThread();
- error = EGL14.eglGetError();
- if (error != EGL14.EGL_SUCCESS) {
- throw new RuntimeException("error releasing thread: " + error);
- }
-
- EGL14.eglTerminate(eglDisplay);
- error = EGL14.eglGetError();
- if (error != EGL14.EGL_SUCCESS) {
- throw new RuntimeException("error terminating display: " + error);
- }
- }
-
- private static EGLConfig getEglConfig(EGLDisplay eglDisplay) {
- // Get an EGLConfig.
- final int EGL_OPENGL_ES2_BIT = 4;
- final int RED_SIZE = 8;
- final int GREEN_SIZE = 8;
- final int BLUE_SIZE = 8;
- final int ALPHA_SIZE = 8;
- final int DEPTH_SIZE = 0;
- final int STENCIL_SIZE = 0;
- final int[] DEFAULT_CONFIGURATION = new int[] {
- EGL14.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL14.EGL_RED_SIZE, RED_SIZE,
- EGL14.EGL_GREEN_SIZE, GREEN_SIZE,
- EGL14.EGL_BLUE_SIZE, BLUE_SIZE,
- EGL14.EGL_ALPHA_SIZE, ALPHA_SIZE,
- EGL14.EGL_DEPTH_SIZE, DEPTH_SIZE,
- EGL14.EGL_STENCIL_SIZE, STENCIL_SIZE,
- EGL14.EGL_NONE};
-
- int[] configsCount = new int[1];
- EGLConfig[] eglConfigs = new EGLConfig[1];
- if (!EGL14.eglChooseConfig(
- eglDisplay, DEFAULT_CONFIGURATION, 0, eglConfigs, 0, 1, configsCount, 0)) {
- throw new RuntimeException("eglChooseConfig failed");
- }
- return eglConfigs[0];
- }
-
- /**
- * Checks for a GL error using {@link GLES20#glGetError()}.
- *
- * @throws RuntimeException if there is a GL error
- */
- private static void checkGlError() {
- int errorCode;
- if ((errorCode = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
- throw new RuntimeException("gl error: " + Integer.toHexString(errorCode));
- }
- }
-
}
diff --git a/tests/tests/graphics/src/android/opengl/cts/EglSurfacesTest.java b/tests/tests/graphics/src/android/opengl/cts/EglSurfacesTest.java
new file mode 100644
index 0000000..c909eeb
--- /dev/null
+++ b/tests/tests/graphics/src/android/opengl/cts/EglSurfacesTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+package android.opengl.cts;
+
+import android.opengl.EGL14;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+
+import static junit.framework.Assert.fail;
+
+/**
+ * Tests using EGL surfaces.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class EglSurfacesTest {
+ @Test
+ public void testCreatePixmapSurface() {
+ // NOTE: This test must use EGL10, which is why we don't reuse GlTestBase
+ EGL10 egl = (EGL10) EGLContext.getEGL();
+ EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+
+ if (display == EGL10.EGL_NO_DISPLAY) {
+ throw new RuntimeException("eglGetDisplay failed");
+ }
+
+ int[] version = new int[2];
+ if (!egl.eglInitialize(display, version)) {
+ throw new RuntimeException("eglInitialize failed");
+ }
+
+ EGLConfig config = Egl10Utils.chooseConfig(egl, display,
+ Egl10Utils.filterConfigSpec(new int[] {
+ EGL10.EGL_RED_SIZE, 8,
+ EGL10.EGL_GREEN_SIZE, 8,
+ EGL10.EGL_BLUE_SIZE, 8,
+ EGL10.EGL_ALPHA_SIZE, 0,
+ EGL10.EGL_DEPTH_SIZE, 0,
+ EGL10.EGL_STENCIL_SIZE, 0,
+ EGL10.EGL_NONE }, 2)
+ );
+
+ int[] contextAttribs = {
+ EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL10.EGL_NONE
+ };
+
+ EGLContext context = egl.eglCreateContext(display, config,
+ EGL10.EGL_NO_CONTEXT, contextAttribs);
+
+ boolean unsupported = false;
+ try {
+ //noinspection deprecation
+ egl.eglCreatePixmapSurface(display, config, null, null);
+ } catch (UnsupportedOperationException e) {
+ unsupported = true;
+ }
+
+ egl.eglDestroyContext(display, context);
+ egl.eglTerminate(display);
+
+ if (!unsupported) {
+ fail("eglCreatePixmapSurface is supported");
+ }
+ }
+}
diff --git a/tests/tests/graphics/src/android/opengl/cts/GlTestBase.java b/tests/tests/graphics/src/android/opengl/cts/GlTestBase.java
new file mode 100644
index 0000000..2350b40
--- /dev/null
+++ b/tests/tests/graphics/src/android/opengl/cts/GlTestBase.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl.cts;
+
+import android.opengl.EGLConfig;
+import android.opengl.EGLContext;
+import android.opengl.EGLDisplay;
+import android.opengl.EGLSurface;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.rules.Timeout;
+
+import static android.opengl.EGL14.EGL_HEIGHT;
+import static android.opengl.EGL14.EGL_NONE;
+import static android.opengl.EGL14.EGL_NO_CONTEXT;
+import static android.opengl.EGL14.EGL_NO_DISPLAY;
+import static android.opengl.EGL14.EGL_NO_SURFACE;
+import static android.opengl.EGL14.EGL_SUCCESS;
+import static android.opengl.EGL14.EGL_WIDTH;
+import static android.opengl.EGL14.eglCreatePbufferSurface;
+import static android.opengl.EGL14.eglDestroySurface;
+import static android.opengl.EGL14.eglGetError;
+import static android.opengl.EGL14.eglMakeCurrent;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+
+/**
+ * Test base for OpenGL ES 2+ tests. This test class initializes and
+ * cleanup EGL before and after each test. Subclasses MUST NOT use
+ * the AndroidJUnit4 runner but JUnit's BlockJUnit4ClassRunner to
+ * guarantee that all methods are run on the same thread (this would
+ * otherwise cause issues with EGL/GL's thread management).
+ *
+ * This implementation relies on EGL14. Do not use this class to
+ * test EGL10.
+ */
+public class GlTestBase {
+ private static EGLDisplay sEglDisplay;
+
+ private EGLContext mEglContext;
+ private EGLSurface mEglSurface;
+
+ @Rule
+ public Timeout mTimeout = new Timeout(2000);
+
+ @BeforeClass
+ public static void initEgl() {
+ sEglDisplay = Egl14Utils.createEglDisplay();
+ assertNotSame(EGL_NO_DISPLAY, sEglDisplay);
+ }
+
+ @AfterClass
+ public static void terminateEgl() {
+ Egl14Utils.releaseAndTerminate(sEglDisplay);
+ }
+
+ @Before
+ public void createContext() {
+ // Requesting OpenGL ES 2.0 context will return an ES 3.0 context on capable devices
+ EGLConfig eglConfig = Egl14Utils.getEglConfig(sEglDisplay, 2);
+ assertEquals(EGL_SUCCESS, eglGetError());
+
+ mEglContext = Egl14Utils.createEglContext(sEglDisplay, eglConfig, 2);
+ assertNotSame(EGL_NO_CONTEXT, eglConfig);
+
+ mEglSurface = eglCreatePbufferSurface(sEglDisplay, eglConfig, new int[] {
+ EGL_WIDTH, 1,
+ EGL_HEIGHT, 1,
+ EGL_NONE
+ }, 0);
+ assertNotSame(EGL_NO_SURFACE, mEglSurface);
+
+ eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, mEglContext);
+ assertEquals(EGL_SUCCESS, eglGetError());
+ }
+
+ @After
+ public void cleanupContext() {
+ eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroySurface(sEglDisplay, mEglSurface);
+ Egl14Utils.destroyEglContext(sEglDisplay, mEglContext);
+ }
+}
diff --git a/tests/tests/graphics/src/android/opengl/cts/ParamsTest.java b/tests/tests/graphics/src/android/opengl/cts/ParamsTest.java
new file mode 100644
index 0000000..96fd81e
--- /dev/null
+++ b/tests/tests/graphics/src/android/opengl/cts/ParamsTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl.cts;
+
+import android.support.test.filters.SmallTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.BlockJUnit4ClassRunner;
+
+import java.nio.IntBuffer;
+
+import static android.opengl.GLES20.glDeleteBuffers;
+import static android.opengl.GLES30.glGenBuffers;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for parameters validation.
+ */
+@SmallTest
+@RunWith(BlockJUnit4ClassRunner.class) // DO NOT USE AndroidJUnit4, it messes up threading
+public class ParamsTest extends GlTestBase {
+ @Test(expected = IllegalArgumentException.class)
+ public void testNullBufferParam() {
+ glGenBuffers(1, null);
+ }
+
+ @Test
+ public void testBufferParam() {
+ IntBuffer buffer = IntBuffer.allocate(1);
+ glGenBuffers(1, buffer);
+
+ assertTrue(buffer.get() > 0);
+
+ buffer.rewind();
+ glDeleteBuffers(1, buffer);
+ }
+}
diff --git a/tests/tests/icu/Android.mk b/tests/tests/icu/Android.mk
index 4867268..45fed49 100644
--- a/tests/tests/icu/Android.mk
+++ b/tests/tests/icu/Android.mk
@@ -42,22 +42,3 @@
include $(BUILD_CTS_SUPPORT_PACKAGE)
-# build cts-icu-tools tool
-# ============================================================
-include $(CLEAR_VARS)
-
-# Don't include this package in any target
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, tools)
-LOCAL_JAVA_RESOURCE_DIRS := resources
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- descGen \
- jsr305lib
-
-LOCAL_JAVA_LIBRARIES := tradefed
-
-LOCAL_MODULE := cts-icu-tools
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
index 6deaed4..4a4ea98 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
@@ -271,12 +271,12 @@
continue;
}
}
- if ((i > 0) && ((i % 8 ) == 0)) {
+ if ((i >= 64) && ((i % 8 ) == 0)) {
keyGenerator.init(spec, rng);
SecretKey key = keyGenerator.generateKey();
assertEquals(i, TestUtils.getKeyInfo(key).getKeySize());
assertEquals((i + 7) / 8, rng.getOutputSizeBytes());
- } else {
+ } else if (i >= 64) {
try {
keyGenerator.init(spec, rng);
fail();
diff --git a/tests/tests/libcoreoj/Android.mk b/tests/tests/libcoreoj/Android.mk
deleted file mode 100644
index e2af4af..0000000
--- a/tests/tests/libcoreoj/Android.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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 := $(harmony_jdwp_test_src_files)
-LOCAL_STATIC_JAVA_LIBRARIES := core-ojtests-public
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := CtsLibcoreOj
-LOCAL_NO_EMMA_INSTRUMENT := true
-LOCAL_NO_EMMA_COMPILE := true
-LOCAL_CTS_TEST_PACKAGE := android.libcore.oj
-LOCAL_CTS_TARGET_RUNTIME_ARGS := cts_jdwp_test_runtime_target := dalvikvm|\#ABI\#|
-LOCAL_CTS_TESTCASE_XML_INPUT := $(LOCAL_PATH)/CtsTestPackage.xml
-# Also include the source code as part of the jar. DO NOT REMOVE.
-# FIXME: build/core/java_library.mk:14: *** cts/tests/tests/libcoreoj: Target java libraries may not set LOCAL_ASSET_DIR.
-#LOCAL_ASSET_DIR := libcore/ojluni/src/test
-include $(BUILD_CTS_TARGET_TESTNG_PACKAGE)
diff --git a/tests/tests/libcoreoj/AndroidTest.xml b/tests/tests/libcoreoj/AndroidTest.xml
deleted file mode 100644
index 7bb02ad..0000000
--- a/tests/tests/libcoreoj/AndroidTest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Base config for libcore OJ testing in CTS">
- <include name="common-config" />
- <!-- Removes temporary dalvik-cache directory created by JDWP tests -->
- <option name="run-command:teardown-command" value="rm -rf /data/local/tmp/dalvik-cache" />
-</configuration>
diff --git a/tests/tests/libcoreoj/CtsTestPackage.xml b/tests/tests/libcoreoj/CtsTestPackage.xml
deleted file mode 100644
index 51fb7fc..0000000
--- a/tests/tests/libcoreoj/CtsTestPackage.xml
+++ /dev/null
@@ -1,440 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<TestPackage name="CtsLibcoreOj" appPackageName="android.libcore.oj" version="1.0" testType="testNGDeviceTest" jarPath="CtsLibcoreOj.jar">
- <TestSuite name="org">
- <TestSuite name="openjdk">
- <TestSuite name="tests">
- <TestSuite name="java">
- <TestSuite name="util">
- <TestSuite name="stream">
- <TestCase name="CollectionAndMapModifyStreamTest">
- <Test name="testCollectionSizeRemove" />
- <Test name="testMapEntriesSizeRemove" />
- <Test name="testMapKeysSizeRemove" />
- <Test name="testMapValuesSizeRemove" />
- </TestCase>
- <TestCase name="ConcatOpTest">
- <Test name="testDoubleSize" />
- <Test name="testIntSize" />
- <Test name="testLongSize" />
- <Test name="testOps" />
- <Test name="testSize" />
- </TestCase>
- <TestCase name="ConcatTest">
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testDoubleConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testIntConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testLongConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- <Test name="testRefConcat" />
- </TestCase>
- <TestCase name="CountLargeTest">
- <Test name="testDoubleLarge" />
- <Test name="testIntLarge" />
- <Test name="testLongLarge" />
- <Test name="testRefLarge" />
- </TestCase>
- <TestCase name="CountTest">
- <Test name="testOps" />
- <Test name="testOps" />
- <Test name="testOps" />
- <Test name="testOps" />
- </TestCase>
- <TestCase name="DistinctOpTest">
- <Test name="testDistinctDistinct" />
- <Test name="testDistinctSorted" />
- <Test name="testOp" />
- <Test name="testOpWithNull" />
- <Test name="testOpWithNullSorted" />
- <Test name="testSortedDistinct" />
- <Test name="testStable" />
- <Test name="testUniqOp" />
- <Test name="testWithUnorderedInfiniteStream" />
- </TestCase>
- <TestCase name="DoublePrimitiveOpsTests">
- <Test name="testLimit" />
- <Test name="testSort" />
- <Test name="testSortSort" />
- <Test name="testToArray" />
- <Test name="testUnBox" />
- </TestCase>
- <TestCase name="ExplodeOpTest">
- <Test name="testDoubleOps" />
- <Test name="testFlatMap" />
- <Test name="testIntOps" />
- <Test name="testLongOps" />
- <Test name="testOps" />
- </TestCase>
- <TestCase name="FilterOpTest">
- <Test name="testFilter" />
- <Test name="testOps" />
- <Test name="testOps" />
- <Test name="testOps" />
- <Test name="testOps" />
- </TestCase>
- <TestCase name="FindAnyOpTest">
- <Test name="testDoubleStream" />
- <Test name="testFindAny" />
- <Test name="testFindAnyParallel" />
- <Test name="testIntStream" />
- <Test name="testLongStream" />
- <Test name="testStream" />
- </TestCase>
- <TestCase name="FindFirstOpTest">
- <Test name="testDoubleStream" />
- <Test name="testFindFirst" />
- <Test name="testIntStream" />
- <Test name="testLongStream" />
- <Test name="testStream" />
- </TestCase>
- <TestCase name="ForEachOpTest">
- <Test name="testDoubleForEachOrdered" />
- <Test name="testDoubleOps" />
- <Test name="testForEach" />
- <Test name="testForEach" />
- <Test name="testForEachOrdered" />
- <Test name="testIntForEach" />
- <Test name="testIntForEachOrdered" />
- <Test name="testLongForEachOrdered" />
- <Test name="testLongOps" />
- </TestCase>
- <TestCase name="GroupByOpTest">
- <Test name="testBypassCollect" />
- <Test name="testGroupBy" />
- <Test name="testOps" />
- </TestCase>
- <TestCase name="InfiniteStreamWithLimitOpTest">
- <Test name="testDoubleSubsizedWithRange" />
- <Test name="testDoubleUnorderedFinite" />
- <Test name="testDoubleUnorderedGenerator" />
- <Test name="testDoubleUnorderedIteration" />
- <Test name="testDoubleUnorderedSizedNotSubsizedFinite" />
- <Test name="testIntSubsizedWithRange" />
- <Test name="testIntUnorderedFinite" />
- <Test name="testIntUnorderedGenerator" />
- <Test name="testIntUnorderedIteration" />
- <Test name="testIntUnorderedSizedNotSubsizedFinite" />
- <Test name="testLongSubsizedWithRange" />
- <Test name="testLongUnorderedFinite" />
- <Test name="testLongUnorderedGenerator" />
- <Test name="testLongUnorderedIteration" />
- <Test name="testLongUnorderedSizedNotSubsizedFinite" />
- <Test name="testSubsizedWithRange" />
- <Test name="testUnorderedFinite" />
- <Test name="testUnorderedGenerator" />
- <Test name="testUnorderedIteration" />
- <Test name="testUnorderedSizedNotSubsizedFinite" />
- </TestCase>
- <TestCase name="IntPrimitiveOpsTests">
- <Test name="testBox" />
- <Test name="testForEach" />
- <Test name="testLimit" />
- <Test name="testMap" />
- <Test name="testParForEach" />
- <Test name="testParSum" />
- <Test name="testSequential" />
- <Test name="testSort" />
- <Test name="testSortSort" />
- <Test name="testSum" />
- <Test name="testTee" />
- <Test name="testToArray" />
- <Test name="testUnBox" />
- </TestCase>
- <TestCase name="IntReduceTest">
- <Test name="testOps" />
- <Test name="testReduce" />
- </TestCase>
- <TestCase name="IntSliceOpTest">
- <Test name="testLimit" />
- <Test name="testLimitOps" />
- <Test name="testLimitParallel" />
- <Test name="testLimitShortCircuit" />
- <Test name="testLimitSort" />
- <Test name="testSkip" />
- <Test name="testSkipLimit" />
- <Test name="testSkipLimitOps" />
- <Test name="testSkipOps" />
- <Test name="testSkipParallel" />
- </TestCase>
- <TestCase name="IntUniqOpTest">
- <Test name="testOp" />
- <Test name="testOpSorted" />
- <Test name="testUniqOp" />
- </TestCase>
- <TestCase name="LongPrimitiveOpsTests">
- <Test name="testBox" />
- <Test name="testForEach" />
- <Test name="testLimit" />
- <Test name="testMap" />
- <Test name="testParForEach" />
- <Test name="testParSum" />
- <Test name="testSequential" />
- <Test name="testSort" />
- <Test name="testSortSort" />
- <Test name="testSum" />
- <Test name="testTee" />
- <Test name="testToArray" />
- <Test name="testUnBox" />
- </TestCase>
- <TestCase name="MapOpTest">
- <Test name="testDoubleOps" />
- <Test name="testEveryMapShape" />
- <Test name="testIntOps" />
- <Test name="testLongOps" />
- <Test name="testMap" />
- <Test name="testOps" />
- </TestCase>
- <TestCase name="MatchOpTest">
- <Test name="testDoubleInfinite" />
- <Test name="testDoubleStream" />
- <Test name="testDoubleStreamMatches" />
- <Test name="testInfinite" />
- <Test name="testIntInfinite" />
- <Test name="testIntStream" />
- <Test name="testIntStreamMatches" />
- <Test name="testLongInfinite" />
- <Test name="testLongStream" />
- <Test name="testLongStreamMatches" />
- <Test name="testStream" />
- <Test name="testStreamMatches" />
- </TestCase>
- <TestCase name="MinMaxTest">
- <Test name="testDoubleMinMax" />
- <Test name="testDoubleOps" />
- <Test name="testIntMinMax" />
- <Test name="testIntOps" />
- <Test name="testLongMinMax" />
- <Test name="testLongOps" />
- <Test name="testMinMax" />
- <Test name="testOps" />
- </TestCase>
- <TestCase name="PrimitiveAverageOpTest">
- <Test name="testOps" />
- <Test name="testOps" />
- <Test name="testOps" />
- </TestCase>
- <TestCase name="PrimitiveSumTest">
- <Test name="testOps" />
- <Test name="testOps" />
- <Test name="testOps" />
- </TestCase>
- <TestCase name="RangeTest">
- <Test name="tesIntRangeReduce" />
- <Test name="testInfiniteRangeFindFirst" />
- <Test name="testIntInfiniteRangeFindFirst" />
- <Test name="testIntInfiniteRangeLimit" />
- <Test name="testIntRange" />
- <Test name="testLongInfiniteRangeFindFirst" />
- <Test name="testLongInfiniteRangeLimit" />
- <Test name="testLongLongRange" />
- <Test name="testLongLongRangeClosed" />
- <Test name="testLongRange" />
- <Test name="testLongRangeReduce" />
- </TestCase>
- <TestCase name="ReduceByOpTest">
- <Test name="testOps" />
- </TestCase>
- <TestCase name="ReduceTest">
- <Test name="testOps" />
- <Test name="testReduce" />
- </TestCase>
- <TestCase name="SequentialOpTest">
- <Test name="testLazy" />
- <Test name="testMixedSeqPar" />
- </TestCase>
- <TestCase name="SliceOpTest">
- <Test name="testLimit" />
- <Test name="testLimitOps" />
- <Test name="testLimitShortCircuit" />
- <Test name="testLimitSort" />
- <Test name="testSkip" />
- <Test name="testSkipLimit" />
- <Test name="testSkipLimitOps" />
- <Test name="testSkipLimitOpsWithNonSplittingSpliterator" />
- <Test name="testSkipOps" />
- <Test name="testSlice" />
- </TestCase>
- <TestCase name="SortedOpTest">
- <Test name="testDoubleOps" />
- <Test name="testDoubleSequentialShortCircuitTerminal" />
- <Test name="testDoubleSortSort" />
- <Test name="testDoubleStreamTooLarge" />
- <Test name="testIntOps" />
- <Test name="testIntSequentialShortCircuitTerminal" />
- <Test name="testIntSortSort" />
- <Test name="testIntStreamTooLarge" />
- <Test name="testLongOps" />
- <Test name="testLongSequentialShortCircuitTerminal" />
- <Test name="testLongSortSort" />
- <Test name="testLongStreamTooLarge" />
- <Test name="testOps" />
- <Test name="testRefStreamTooLarge" />
- <Test name="testSequentialShortCircuitTerminal" />
- <Test name="testSortSort" />
- <Test name="testSorted" />
- </TestCase>
- <TestCase name="SpliteratorTest">
- <Test name="testDoubleSpliterator" />
- <Test name="testIntSpliterator" />
- <Test name="testLongSpliterator" />
- <Test name="testSpliterator" />
- </TestCase>
- <TestCase name="StreamBuilderTest">
- <Test name="testAfterBuilding" />
- <Test name="testDoubleAfterBuilding" />
- <Test name="testDoubleSingleton" />
- <Test name="testDoubleStreamBuilder" />
- <Test name="testIntAfterBuilding" />
- <Test name="testIntSingleton" />
- <Test name="testIntStreamBuilder" />
- <Test name="testLongAfterBuilding" />
- <Test name="testLongSingleton" />
- <Test name="testLongStreamBuilder" />
- <Test name="testSingleton" />
- <Test name="testStreamBuilder" />
- </TestCase>
- <TestCase name="StreamCloseTest">
- <Test name="testCascadedExceptions" />
- <Test name="testEmptyCloseHandler" />
- <Test name="testOneCloseHandler" />
- <Test name="testTwoCloseHandlers" />
- </TestCase>
- <TestCase name="StreamLinkTest">
- <Test name="testDoubleManyStreams" />
- <Test name="testIntManyStreams" />
- <Test name="testLongManyStreams" />
- <Test name="testManyStreams" />
- </TestCase>
- <TestCase name="StreamParSeqTest">
- <Test name="testParSeq" />
- </TestCase>
- <TestCase name="StreamSpliteratorTest">
- <Test name="testDoubleParSpliterators" />
- <Test name="testDoubleSpliterators" />
- <Test name="testDoubleSplitting" />
- <Test name="testDoubleStreamSpliterators" />
- <Test name="testIntParSpliterators" />
- <Test name="testIntSpliterators" />
- <Test name="testIntSplitting" />
- <Test name="testIntStreamSpliterators" />
- <Test name="testLongParSpliterators" />
- <Test name="testLongSpliterators" />
- <Test name="testLongSplitting" />
- <Test name="testLongStreamSpliterators" />
- <Test name="testParSpliterators" />
- <Test name="testSpliterators" />
- <Test name="testSplitting" />
- <Test name="testStreamSpliterators" />
- </TestCase>
- <TestCase name="SummaryStatisticsTest">
- <Test name="testDoubleStatistics" />
- <Test name="testIntStatistics" />
- <Test name="testLongStatistics" />
- </TestCase>
- <TestCase name="TabulatorsTest">
- <Test name="testComposeFinisher" />
- <Test name="testGroupedReduce" />
- <Test name="testJoin" />
- <Test name="testReduce" />
- <Test name="testSimpleGroupBy" />
- <Test name="testSimplePartition" />
- <Test name="testSimpleToMap" />
- <Test name="testTwoLevelGroupBy" />
- <Test name="testTwoLevelPartition" />
- </TestCase>
- <TestCase name="TeeOpTest">
- <Test name="testDoubleOps" />
- <Test name="testIntOps" />
- <Test name="testLongOps" />
- <Test name="testOps" />
- <Test name="testTee" />
- </TestCase>
- <TestCase name="ToArrayOpTest">
- <Test name="testAsArrayWithType" />
- <Test name="testDistinctAndSortedPermutations" />
- <Test name="testDoubleDistinctAndSortedPermutations" />
- <Test name="testDoubleOps" />
- <Test name="testDoubleOpsWithFilter" />
- <Test name="testDoubleOpsWithFlatMap" />
- <Test name="testDoubleOpsWithMap" />
- <Test name="testDoubleOpsWithSorted" />
- <Test name="testDoubleStatefulOpPermutations" />
- <Test name="testIntDistinctAndSortedPermutations" />
- <Test name="testIntOps" />
- <Test name="testIntOpsWithFilter" />
- <Test name="testIntOpsWithFlatMap" />
- <Test name="testIntOpsWithMap" />
- <Test name="testIntOpsWithSorted" />
- <Test name="testIntStatefulOpPermutations" />
- <Test name="testLongDistinctAndSortedPermutations" />
- <Test name="testLongOps" />
- <Test name="testLongOpsWithFilter" />
- <Test name="testLongOpsWithFlatMap" />
- <Test name="testLongOpsWithMap" />
- <Test name="testLongOpsWithSorted" />
- <Test name="testLongStatefulOpPermutations" />
- <Test name="testOps" />
- <Test name="testOpsWithFilter" />
- <Test name="testOpsWithFlatMap" />
- <Test name="testOpsWithMap" />
- <Test name="testOpsWithSorted" />
- <Test name="testStatefulOpPermutations" />
- <Test name="testToArray" />
- </TestCase>
- </TestSuite>
- <TestCase name="FillableStringTest">
- <Test name="testStringBuffer" />
- <Test name="testStringBuilder" />
- <Test name="testStringJoiner" />
- </TestCase>
- <TestCase name="MapTest">
- <Test name="testForEach" />
- <Test name="testReplaceAll" />
- </TestCase>
- </TestSuite>
- </TestSuite>
- </TestSuite>
- </TestSuite>
- </TestSuite>
-</TestPackage>
diff --git a/tests/tests/libcoreoj/gen-test-list-xml b/tests/tests/libcoreoj/gen-test-list-xml
deleted file mode 100755
index fc61646..0000000
--- a/tests/tests/libcoreoj/gen-test-list-xml
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-
-#
-# Usage:
-# -- Update test_list.txt with new tests/methods whenever new code is added.
-# -- Run this script ./gen-test-list-xml
-# -- Save the updated .xml file into the build, so ctsv1 knows how to run our testng tests.
-#
-
-test_list_txt=$DIR/test_list.txt
-[[ -f $test_list_txt ]] || echo "Can't find $test_list_txt" >&2
-
-$DIR/../../../tools/testng/gen-test-list-xml.py --app-package-name android.libcore.oj --cts-name CtsLibcoreOj --jar-path CtsLibcoreOj.jar $DIR/test_list.txt
diff --git a/tests/tests/libcoreoj/test_list.txt b/tests/tests/libcoreoj/test_list.txt
deleted file mode 100644
index 9195c26..0000000
--- a/tests/tests/libcoreoj/test_list.txt
+++ /dev/null
@@ -1,341 +0,0 @@
-org.openjdk.tests.java.util.stream.CollectionAndMapModifyStreamTest#testCollectionSizeRemove
-org.openjdk.tests.java.util.stream.CollectionAndMapModifyStreamTest#testMapEntriesSizeRemove
-org.openjdk.tests.java.util.stream.CollectionAndMapModifyStreamTest#testMapKeysSizeRemove
-org.openjdk.tests.java.util.stream.CollectionAndMapModifyStreamTest#testMapValuesSizeRemove
-org.openjdk.tests.java.util.stream.ConcatOpTest#testDoubleSize
-org.openjdk.tests.java.util.stream.ConcatOpTest#testIntSize
-org.openjdk.tests.java.util.stream.ConcatOpTest#testLongSize
-org.openjdk.tests.java.util.stream.ConcatOpTest#testOps
-org.openjdk.tests.java.util.stream.ConcatOpTest#testSize
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testDoubleConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testIntConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testLongConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.ConcatTest#testRefConcat
-org.openjdk.tests.java.util.stream.CountLargeTest#testDoubleLarge
-org.openjdk.tests.java.util.stream.CountLargeTest#testIntLarge
-org.openjdk.tests.java.util.stream.CountLargeTest#testLongLarge
-org.openjdk.tests.java.util.stream.CountLargeTest#testRefLarge
-org.openjdk.tests.java.util.stream.CountTest#testOps
-org.openjdk.tests.java.util.stream.CountTest#testOps
-org.openjdk.tests.java.util.stream.CountTest#testOps
-org.openjdk.tests.java.util.stream.CountTest#testOps
-org.openjdk.tests.java.util.stream.DistinctOpTest#testDistinctDistinct
-org.openjdk.tests.java.util.stream.DistinctOpTest#testDistinctSorted
-org.openjdk.tests.java.util.stream.DistinctOpTest#testOp
-org.openjdk.tests.java.util.stream.DistinctOpTest#testOpWithNull
-org.openjdk.tests.java.util.stream.DistinctOpTest#testOpWithNullSorted
-org.openjdk.tests.java.util.stream.DistinctOpTest#testSortedDistinct
-org.openjdk.tests.java.util.stream.DistinctOpTest#testStable
-org.openjdk.tests.java.util.stream.DistinctOpTest#testUniqOp
-org.openjdk.tests.java.util.stream.DistinctOpTest#testWithUnorderedInfiniteStream
-org.openjdk.tests.java.util.stream.DoublePrimitiveOpsTests#testLimit
-org.openjdk.tests.java.util.stream.DoublePrimitiveOpsTests#testSort
-org.openjdk.tests.java.util.stream.DoublePrimitiveOpsTests#testSortSort
-org.openjdk.tests.java.util.stream.DoublePrimitiveOpsTests#testToArray
-org.openjdk.tests.java.util.stream.DoublePrimitiveOpsTests#testUnBox
-org.openjdk.tests.java.util.stream.ExplodeOpTest#testDoubleOps
-org.openjdk.tests.java.util.stream.ExplodeOpTest#testFlatMap
-org.openjdk.tests.java.util.stream.ExplodeOpTest#testIntOps
-org.openjdk.tests.java.util.stream.ExplodeOpTest#testLongOps
-org.openjdk.tests.java.util.stream.ExplodeOpTest#testOps
-org.openjdk.tests.java.util.FillableStringTest#testStringBuffer
-org.openjdk.tests.java.util.FillableStringTest#testStringBuilder
-org.openjdk.tests.java.util.FillableStringTest#testStringJoiner
-org.openjdk.tests.java.util.stream.FilterOpTest#testFilter
-org.openjdk.tests.java.util.stream.FilterOpTest#testOps
-org.openjdk.tests.java.util.stream.FilterOpTest#testOps
-org.openjdk.tests.java.util.stream.FilterOpTest#testOps
-org.openjdk.tests.java.util.stream.FilterOpTest#testOps
-org.openjdk.tests.java.util.stream.FindAnyOpTest#testDoubleStream
-org.openjdk.tests.java.util.stream.FindAnyOpTest#testFindAny
-org.openjdk.tests.java.util.stream.FindAnyOpTest#testFindAnyParallel
-org.openjdk.tests.java.util.stream.FindAnyOpTest#testIntStream
-org.openjdk.tests.java.util.stream.FindAnyOpTest#testLongStream
-org.openjdk.tests.java.util.stream.FindAnyOpTest#testStream
-org.openjdk.tests.java.util.stream.FindFirstOpTest#testDoubleStream
-org.openjdk.tests.java.util.stream.FindFirstOpTest#testFindFirst
-org.openjdk.tests.java.util.stream.FindFirstOpTest#testIntStream
-org.openjdk.tests.java.util.stream.FindFirstOpTest#testLongStream
-org.openjdk.tests.java.util.stream.FindFirstOpTest#testStream
-org.openjdk.tests.java.util.stream.ForEachOpTest#testDoubleForEachOrdered
-org.openjdk.tests.java.util.stream.ForEachOpTest#testDoubleOps
-org.openjdk.tests.java.util.stream.ForEachOpTest#testForEach
-org.openjdk.tests.java.util.stream.ForEachOpTest#testForEach
-org.openjdk.tests.java.util.stream.ForEachOpTest#testForEachOrdered
-org.openjdk.tests.java.util.stream.ForEachOpTest#testIntForEach
-org.openjdk.tests.java.util.stream.ForEachOpTest#testIntForEachOrdered
-org.openjdk.tests.java.util.stream.ForEachOpTest#testLongForEachOrdered
-org.openjdk.tests.java.util.stream.ForEachOpTest#testLongOps
-org.openjdk.tests.java.util.stream.GroupByOpTest#testBypassCollect
-org.openjdk.tests.java.util.stream.GroupByOpTest#testGroupBy
-org.openjdk.tests.java.util.stream.GroupByOpTest#testOps
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testDoubleSubsizedWithRange
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testDoubleUnorderedFinite
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testDoubleUnorderedGenerator
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testDoubleUnorderedIteration
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testDoubleUnorderedSizedNotSubsizedFinite
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testIntSubsizedWithRange
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testIntUnorderedFinite
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testIntUnorderedGenerator
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testIntUnorderedIteration
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testIntUnorderedSizedNotSubsizedFinite
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testLongSubsizedWithRange
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testLongUnorderedFinite
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testLongUnorderedGenerator
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testLongUnorderedIteration
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testLongUnorderedSizedNotSubsizedFinite
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testSubsizedWithRange
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testUnorderedFinite
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testUnorderedGenerator
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testUnorderedIteration
-org.openjdk.tests.java.util.stream.InfiniteStreamWithLimitOpTest#testUnorderedSizedNotSubsizedFinite
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testBox
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testForEach
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testLimit
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testMap
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testParForEach
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testParSum
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testSequential
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testSort
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testSortSort
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testSum
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testTee
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testToArray
-org.openjdk.tests.java.util.stream.IntPrimitiveOpsTests#testUnBox
-org.openjdk.tests.java.util.stream.IntReduceTest#testOps
-org.openjdk.tests.java.util.stream.IntReduceTest#testReduce
-org.openjdk.tests.java.util.stream.IntSliceOpTest#testLimit
-org.openjdk.tests.java.util.stream.IntSliceOpTest#testLimitOps
-org.openjdk.tests.java.util.stream.IntSliceOpTest#testLimitParallel
-org.openjdk.tests.java.util.stream.IntSliceOpTest#testLimitShortCircuit
-org.openjdk.tests.java.util.stream.IntSliceOpTest#testLimitSort
-org.openjdk.tests.java.util.stream.IntSliceOpTest#testSkip
-org.openjdk.tests.java.util.stream.IntSliceOpTest#testSkipLimit
-org.openjdk.tests.java.util.stream.IntSliceOpTest#testSkipLimitOps
-org.openjdk.tests.java.util.stream.IntSliceOpTest#testSkipOps
-org.openjdk.tests.java.util.stream.IntSliceOpTest#testSkipParallel
-org.openjdk.tests.java.util.stream.IntUniqOpTest#testOp
-org.openjdk.tests.java.util.stream.IntUniqOpTest#testOpSorted
-org.openjdk.tests.java.util.stream.IntUniqOpTest#testUniqOp
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testBox
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testForEach
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testLimit
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testMap
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testParForEach
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testParSum
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testSequential
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testSort
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testSortSort
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testSum
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testTee
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testToArray
-org.openjdk.tests.java.util.stream.LongPrimitiveOpsTests#testUnBox
-org.openjdk.tests.java.util.stream.MapOpTest#testDoubleOps
-org.openjdk.tests.java.util.stream.MapOpTest#testEveryMapShape
-org.openjdk.tests.java.util.stream.MapOpTest#testIntOps
-org.openjdk.tests.java.util.stream.MapOpTest#testLongOps
-org.openjdk.tests.java.util.stream.MapOpTest#testMap
-org.openjdk.tests.java.util.stream.MapOpTest#testOps
-org.openjdk.tests.java.util.MapTest#testForEach
-org.openjdk.tests.java.util.MapTest#testReplaceAll
-org.openjdk.tests.java.util.stream.MatchOpTest#testDoubleInfinite
-org.openjdk.tests.java.util.stream.MatchOpTest#testDoubleStream
-org.openjdk.tests.java.util.stream.MatchOpTest#testDoubleStreamMatches
-org.openjdk.tests.java.util.stream.MatchOpTest#testInfinite
-org.openjdk.tests.java.util.stream.MatchOpTest#testIntInfinite
-org.openjdk.tests.java.util.stream.MatchOpTest#testIntStream
-org.openjdk.tests.java.util.stream.MatchOpTest#testIntStreamMatches
-org.openjdk.tests.java.util.stream.MatchOpTest#testLongInfinite
-org.openjdk.tests.java.util.stream.MatchOpTest#testLongStream
-org.openjdk.tests.java.util.stream.MatchOpTest#testLongStreamMatches
-org.openjdk.tests.java.util.stream.MatchOpTest#testStream
-org.openjdk.tests.java.util.stream.MatchOpTest#testStreamMatches
-org.openjdk.tests.java.util.stream.MinMaxTest#testDoubleMinMax
-org.openjdk.tests.java.util.stream.MinMaxTest#testDoubleOps
-org.openjdk.tests.java.util.stream.MinMaxTest#testIntMinMax
-org.openjdk.tests.java.util.stream.MinMaxTest#testIntOps
-org.openjdk.tests.java.util.stream.MinMaxTest#testLongMinMax
-org.openjdk.tests.java.util.stream.MinMaxTest#testLongOps
-org.openjdk.tests.java.util.stream.MinMaxTest#testMinMax
-org.openjdk.tests.java.util.stream.MinMaxTest#testOps
-org.openjdk.tests.java.util.stream.PrimitiveAverageOpTest#testOps
-org.openjdk.tests.java.util.stream.PrimitiveAverageOpTest#testOps
-org.openjdk.tests.java.util.stream.PrimitiveAverageOpTest#testOps
-org.openjdk.tests.java.util.stream.PrimitiveSumTest#testOps
-org.openjdk.tests.java.util.stream.PrimitiveSumTest#testOps
-org.openjdk.tests.java.util.stream.PrimitiveSumTest#testOps
-org.openjdk.tests.java.util.stream.RangeTest#tesIntRangeReduce
-org.openjdk.tests.java.util.stream.RangeTest#testInfiniteRangeFindFirst
-org.openjdk.tests.java.util.stream.RangeTest#testIntInfiniteRangeFindFirst
-org.openjdk.tests.java.util.stream.RangeTest#testIntInfiniteRangeLimit
-org.openjdk.tests.java.util.stream.RangeTest#testIntRange
-org.openjdk.tests.java.util.stream.RangeTest#testLongInfiniteRangeFindFirst
-org.openjdk.tests.java.util.stream.RangeTest#testLongInfiniteRangeLimit
-org.openjdk.tests.java.util.stream.RangeTest#testLongLongRange
-org.openjdk.tests.java.util.stream.RangeTest#testLongLongRangeClosed
-org.openjdk.tests.java.util.stream.RangeTest#testLongRange
-org.openjdk.tests.java.util.stream.RangeTest#testLongRangeReduce
-org.openjdk.tests.java.util.stream.ReduceByOpTest#testOps
-org.openjdk.tests.java.util.stream.ReduceTest#testOps
-org.openjdk.tests.java.util.stream.ReduceTest#testReduce
-org.openjdk.tests.java.util.stream.SequentialOpTest#testLazy
-org.openjdk.tests.java.util.stream.SequentialOpTest#testMixedSeqPar
-org.openjdk.tests.java.util.stream.SliceOpTest#testLimit
-org.openjdk.tests.java.util.stream.SliceOpTest#testLimitOps
-org.openjdk.tests.java.util.stream.SliceOpTest#testLimitShortCircuit
-org.openjdk.tests.java.util.stream.SliceOpTest#testLimitSort
-org.openjdk.tests.java.util.stream.SliceOpTest#testSkip
-org.openjdk.tests.java.util.stream.SliceOpTest#testSkipLimit
-org.openjdk.tests.java.util.stream.SliceOpTest#testSkipLimitOps
-org.openjdk.tests.java.util.stream.SliceOpTest#testSkipLimitOpsWithNonSplittingSpliterator
-org.openjdk.tests.java.util.stream.SliceOpTest#testSkipOps
-org.openjdk.tests.java.util.stream.SliceOpTest#testSlice
-org.openjdk.tests.java.util.stream.SortedOpTest#testDoubleOps
-org.openjdk.tests.java.util.stream.SortedOpTest#testDoubleSequentialShortCircuitTerminal
-org.openjdk.tests.java.util.stream.SortedOpTest#testDoubleSortSort
-org.openjdk.tests.java.util.stream.SortedOpTest#testDoubleStreamTooLarge
-org.openjdk.tests.java.util.stream.SortedOpTest#testIntOps
-org.openjdk.tests.java.util.stream.SortedOpTest#testIntSequentialShortCircuitTerminal
-org.openjdk.tests.java.util.stream.SortedOpTest#testIntSortSort
-org.openjdk.tests.java.util.stream.SortedOpTest#testIntStreamTooLarge
-org.openjdk.tests.java.util.stream.SortedOpTest#testLongOps
-org.openjdk.tests.java.util.stream.SortedOpTest#testLongSequentialShortCircuitTerminal
-org.openjdk.tests.java.util.stream.SortedOpTest#testLongSortSort
-org.openjdk.tests.java.util.stream.SortedOpTest#testLongStreamTooLarge
-org.openjdk.tests.java.util.stream.SortedOpTest#testOps
-org.openjdk.tests.java.util.stream.SortedOpTest#testRefStreamTooLarge
-org.openjdk.tests.java.util.stream.SortedOpTest#testSequentialShortCircuitTerminal
-org.openjdk.tests.java.util.stream.SortedOpTest#testSortSort
-org.openjdk.tests.java.util.stream.SortedOpTest#testSorted
-org.openjdk.tests.java.util.stream.SpliteratorTest#testDoubleSpliterator
-org.openjdk.tests.java.util.stream.SpliteratorTest#testIntSpliterator
-org.openjdk.tests.java.util.stream.SpliteratorTest#testLongSpliterator
-org.openjdk.tests.java.util.stream.SpliteratorTest#testSpliterator
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testAfterBuilding
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testDoubleAfterBuilding
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testDoubleSingleton
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testDoubleStreamBuilder
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testIntAfterBuilding
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testIntSingleton
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testIntStreamBuilder
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testLongAfterBuilding
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testLongSingleton
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testLongStreamBuilder
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testSingleton
-org.openjdk.tests.java.util.stream.StreamBuilderTest#testStreamBuilder
-org.openjdk.tests.java.util.stream.StreamCloseTest#testCascadedExceptions
-org.openjdk.tests.java.util.stream.StreamCloseTest#testEmptyCloseHandler
-org.openjdk.tests.java.util.stream.StreamCloseTest#testOneCloseHandler
-org.openjdk.tests.java.util.stream.StreamCloseTest#testTwoCloseHandlers
-org.openjdk.tests.java.util.stream.StreamLinkTest#testDoubleManyStreams
-org.openjdk.tests.java.util.stream.StreamLinkTest#testIntManyStreams
-org.openjdk.tests.java.util.stream.StreamLinkTest#testLongManyStreams
-org.openjdk.tests.java.util.stream.StreamLinkTest#testManyStreams
-org.openjdk.tests.java.util.stream.StreamParSeqTest#testParSeq
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testDoubleParSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testDoubleSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testDoubleSplitting
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testDoubleStreamSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testIntParSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testIntSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testIntSplitting
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testIntStreamSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testLongParSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testLongSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testLongSplitting
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testLongStreamSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testParSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testSpliterators
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testSplitting
-org.openjdk.tests.java.util.stream.StreamSpliteratorTest#testStreamSpliterators
-org.openjdk.tests.java.util.stream.SummaryStatisticsTest#testDoubleStatistics
-org.openjdk.tests.java.util.stream.SummaryStatisticsTest#testIntStatistics
-org.openjdk.tests.java.util.stream.SummaryStatisticsTest#testLongStatistics
-org.openjdk.tests.java.util.stream.TabulatorsTest#testComposeFinisher
-org.openjdk.tests.java.util.stream.TabulatorsTest#testGroupedReduce
-org.openjdk.tests.java.util.stream.TabulatorsTest#testJoin
-org.openjdk.tests.java.util.stream.TabulatorsTest#testReduce
-org.openjdk.tests.java.util.stream.TabulatorsTest#testSimpleGroupBy
-org.openjdk.tests.java.util.stream.TabulatorsTest#testSimplePartition
-org.openjdk.tests.java.util.stream.TabulatorsTest#testSimpleToMap
-org.openjdk.tests.java.util.stream.TabulatorsTest#testTwoLevelGroupBy
-org.openjdk.tests.java.util.stream.TabulatorsTest#testTwoLevelPartition
-org.openjdk.tests.java.util.stream.TeeOpTest#testDoubleOps
-org.openjdk.tests.java.util.stream.TeeOpTest#testIntOps
-org.openjdk.tests.java.util.stream.TeeOpTest#testLongOps
-org.openjdk.tests.java.util.stream.TeeOpTest#testOps
-org.openjdk.tests.java.util.stream.TeeOpTest#testTee
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testAsArrayWithType
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testDistinctAndSortedPermutations
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleDistinctAndSortedPermutations
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleOps
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleOpsWithFilter
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleOpsWithFlatMap
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleOpsWithMap
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleOpsWithSorted
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testDoubleStatefulOpPermutations
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntDistinctAndSortedPermutations
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntOps
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntOpsWithFilter
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntOpsWithFlatMap
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntOpsWithMap
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntOpsWithSorted
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testIntStatefulOpPermutations
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongDistinctAndSortedPermutations
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongOps
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongOpsWithFilter
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongOpsWithFlatMap
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongOpsWithMap
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongOpsWithSorted
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testLongStatefulOpPermutations
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testOps
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testOpsWithFilter
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testOpsWithFlatMap
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testOpsWithMap
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testOpsWithSorted
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testStatefulOpPermutations
-org.openjdk.tests.java.util.stream.ToArrayOpTest#testToArray
diff --git a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
index 509be67..662a1fd 100644
--- a/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
+++ b/tests/tests/location/src/android/location/cts/TestMeasurementUtil.java
@@ -55,6 +55,8 @@
" listener has failed, this indicates a platform bug. Please report the issue with" +
" a full bugreport.";
+ private static final int YEAR_2016 = 2016;
+
// The valid Gnss navigation message type as listed in
// android/hardware/libhardware/include/hardware/gps.h
public static final Set<Integer> GNSS_NAVIGATION_MESSAGE_TYPE =
@@ -70,8 +72,6 @@
GnssNavigationMessage.TYPE_GAL_F
));
- private static final int YEAR_2016 = 2016;
-
/**
* Check if test can be run on the current device.
*
diff --git a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
index 7d5742e..69f3ee8 100644
--- a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
+++ b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
@@ -344,24 +344,25 @@
return;
}
- IConnectionStatus wifiStatus = new WifiStatus(mContext);
- if (!wifiStatus.isEnabled()) {
- throw new Error("Wifi is not enabled, please enable Wifi to run tests.");
+ IConnectionStatus connectionStatus = new ConnectionStatus(mContext);
+ if (!connectionStatus.isAvailable()) {
+ throw new Error("Network is not available, reason: " +
+ connectionStatus.getNotConnectedReason());
}
- // If Wifi is not connected, recheck the status a few times.
+
+ // If device is not online, recheck the status a few times.
int retries = 0;
- while (!wifiStatus.isConnected()) {
+ while (!connectionStatus.isConnected()) {
if (retries++ >= CONNECTION_RETRIES) {
- wifiStatus.printConnectionInfo();
- throw new Error("Wifi is not connected, reason: " +
- wifiStatus.getNotConnectedReason());
+ throw new Error("Device is not online, reason: " +
+ connectionStatus.getNotConnectedReason());
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
- wifiStatus.testConnection(videoUrl);
+ connectionStatus.testConnection(videoUrl);
mSessionId = openSession(drm);
mMediaCodecPlayer = new MediaCodecClearKeyPlayer(
diff --git a/tests/tests/media/src/android/media/cts/WifiStatus.java b/tests/tests/media/src/android/media/cts/ConnectionStatus.java
similarity index 77%
rename from tests/tests/media/src/android/media/cts/WifiStatus.java
rename to tests/tests/media/src/android/media/cts/ConnectionStatus.java
index c2577f1..37fc75e 100644
--- a/tests/tests/media/src/android/media/cts/WifiStatus.java
+++ b/tests/tests/media/src/android/media/cts/ConnectionStatus.java
@@ -20,8 +20,6 @@
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
import android.util.Log;
import java.io.BufferedReader;
@@ -32,19 +30,17 @@
/**
* A class that implements IConnectionStatus interface
- * to report and test Wifi connection.
+ * to report and test connection status.
*/
-public class WifiStatus implements IConnectionStatus {
+public class ConnectionStatus implements IConnectionStatus {
- private static final String TAG = "WifiStatus";
+ private static final String TAG = "ConnectionStatus";
private ConnectivityManager mConnectivityManager;
- private WifiManager mWifiManager;
- public WifiStatus(Context context) {
+ public ConnectionStatus(Context context) {
mConnectivityManager =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
- mWifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
}
public String getNotConnectedReason() {
@@ -52,7 +48,7 @@
if (networkInfo != null) {
return networkInfo.getReason();
} else {
- return "Cannot get network info";
+ return "Network info is not available.";
}
}
@@ -66,22 +62,6 @@
return (networkInfo != null) && networkInfo.isConnected();
}
- public boolean isEnabled() {
- return mWifiManager.isWifiEnabled();
- }
-
- public void printConnectionInfo() {
- WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
- if (wifiInfo == null) {
- throw new Error("Fail to get Wifi connection info");
- }
-
- Log.d(TAG, "ssid=" + wifiInfo.getSSID());
- Log.d(TAG, "frequency=" + wifiInfo.getFrequency() + " " + WifiInfo.FREQUENCY_UNITS);
- Log.d(TAG, "rssi=" + wifiInfo.getRssi() + " dBm");
- Log.d(TAG, "link speed=" + wifiInfo.getLinkSpeed() + " " + WifiInfo.LINK_SPEED_UNITS);
- }
-
/**
* Print lines.
*
@@ -152,14 +132,6 @@
}
public void testConnection(Uri uri) {
- final String GOOG = "www.google.com";
-
- if (pingTest(GOOG)) {
- Log.d(TAG, "Successfully pinged " + GOOG);
- } else {
- Log.e(TAG, "Failed to ping " + GOOG);
- }
-
if (pingTest(uri.getHost())) {
Log.d(TAG, "Successfully pinged " + uri.getHost());
} else {
diff --git a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
index ac82a98..9b1dc81 100644
--- a/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
+++ b/tests/tests/media/src/android/media/cts/DecodeAccuracyTest.java
@@ -19,7 +19,9 @@
import android.annotation.TargetApi;
import android.content.Context;
+import android.cts.util.MediaUtils;
import android.graphics.Bitmap;
+import android.media.MediaFormat;
import android.support.test.runner.AndroidJUnit4;
import android.util.Log;
import android.view.View;
@@ -164,17 +166,23 @@
private void runH264DecodeAccuracyTest(
VideoViewFactory videoViewFactory, VideoFormat videoFormat) {
- runDecodeAccuracyTest(videoViewFactory, videoFormat, R.raw.h264decodertestgolden);
+ if (MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+ runDecodeAccuracyTest(videoViewFactory, videoFormat, R.raw.h264decodertestgolden);
+ }
}
private void runVP9DecodeAccuracyTest(
VideoViewFactory videoViewFactory, VideoFormat videoFormat) {
- runDecodeAccuracyTest(videoViewFactory, videoFormat, R.raw.vp9decodertestgolden);
+ if (MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_VP9)) {
+ runDecodeAccuracyTest(videoViewFactory, videoFormat, R.raw.vp9decodertestgolden);
+ }
}
private void runH264DecodeCroppedTest(
VideoViewFactory videoViewFactory, VideoFormat videoFormat) {
- runDecodeAccuracyTest(videoViewFactory, videoFormat, R.raw.h264decodertest520x360golden);
+ if (MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+ runDecodeAccuracyTest(videoViewFactory, videoFormat, R.raw.h264decodertest520x360golden);
+ }
}
private void runDecodeAccuracyTest(
diff --git a/tests/tests/media/src/android/media/cts/IConnectionStatus.java b/tests/tests/media/src/android/media/cts/IConnectionStatus.java
index 39e2781..17d5ff7 100644
--- a/tests/tests/media/src/android/media/cts/IConnectionStatus.java
+++ b/tests/tests/media/src/android/media/cts/IConnectionStatus.java
@@ -29,10 +29,6 @@
public boolean isConnected();
- public boolean isEnabled();
-
- public void printConnectionInfo();
-
public void testConnection(Uri uri);
}
diff --git a/tests/tests/opengl/DEPRECATED b/tests/tests/opengl/DEPRECATED
new file mode 100644
index 0000000..59d5124
--- /dev/null
+++ b/tests/tests/opengl/DEPRECATED
@@ -0,0 +1,3 @@
+This suite of tests is deprecated. Please add OpenGL CTS test to either:
+- dEQP for native tests
+- graphics/src/android/opengl/cts for Java bindings tests
diff --git a/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java
index b7917e2..0b76770 100644
--- a/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/AttachShaderTest.java
@@ -146,4 +146,11 @@
int error = mActivity.glGetError();
assertEquals(GLES20.GL_NO_ERROR, error);
}
+
+ public void test_glCompileShaders_shader_info_log_fail() throws Throwable {
+ mActivity = getShaderActivity(Constants.SHADER, 12);
+ String log = mActivity.glGetInfoLog();
+ assertNotNull(log);
+ assertTrue(log.length() > 0);
+ }
}
diff --git a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java
index 33f097c..0e11165 100644
--- a/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java
+++ b/tests/tests/opengl/src/android/opengl/cts/OpenGLES20ActivityOne.java
@@ -61,6 +61,10 @@
return ((RendererBase)mRenderer).mError;
}
+ public String glGetInfoLog() {
+ return ((RendererBase)mRenderer).mInfoLog;
+ }
+
public boolean waitForFrameDrawn() {
boolean result = false;
try {
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererBase.java b/tests/tests/opengl/src/android/opengl/cts/RendererBase.java
index 994c1c6..a5a281b 100644
--- a/tests/tests/opengl/src/android/opengl/cts/RendererBase.java
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererBase.java
@@ -34,6 +34,7 @@
int[] mShaderCount = null;
int mError;
+ String mInfoLog = null;
// child may need to manipulate them directly
protected CountDownLatch mLatch;
@@ -52,6 +53,7 @@
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
+ mInfoLog = GLES20.glGetShaderInfoLog(shader);
return shader;
}
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererElevenShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/RendererElevenShaderTest.java
index 35df7b5..cc047fa 100644
--- a/tests/tests/opengl/src/android/opengl/cts/RendererElevenShaderTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererElevenShaderTest.java
@@ -22,8 +22,6 @@
import android.opengl.GLES20;
public class RendererElevenShaderTest extends RendererBase {
- private String fragmentShaderCode = Vertex.successfulcompile_vertex;
-
public RendererElevenShaderTest(CountDownLatch latch) {
super(latch);
}
@@ -31,10 +29,10 @@
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
- int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+ int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, Vertex.successfulcompile_vertex);
mProgram = GLES20.glCreateProgram();
- GLES20.glAttachShader(mProgram, fragmentShader);
+ GLES20.glAttachShader(mProgram, vertexShader);
GLES20.glLinkProgram(mProgram);
mError = GLES20.glGetError();
diff --git a/tests/tests/opengl/src/android/opengl/cts/RendererTwelveShaderTest.java b/tests/tests/opengl/src/android/opengl/cts/RendererTwelveShaderTest.java
index a3dab8e..3e18221 100644
--- a/tests/tests/opengl/src/android/opengl/cts/RendererTwelveShaderTest.java
+++ b/tests/tests/opengl/src/android/opengl/cts/RendererTwelveShaderTest.java
@@ -22,7 +22,7 @@
import android.opengl.GLES20;
public class RendererTwelveShaderTest extends RendererBase {
- private String fragmentShaderCode = Shaders.successfulcompile_frag;
+ private String fragmentShaderCode = Shaders.errorcompile_frag;
public RendererTwelveShaderTest(CountDownLatch latch) {
super(latch);
@@ -32,8 +32,6 @@
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
- //invalid value
- mProgram = 0;
GLES20.glAttachShader(mProgram, fragmentShader);
GLES20.glLinkProgram(mProgram);
diff --git a/tests/tests/opengl/src/android/opengl/cts/Shaders.java b/tests/tests/opengl/src/android/opengl/cts/Shaders.java
index e8025fc..7e0113e 100644
--- a/tests/tests/opengl/src/android/opengl/cts/Shaders.java
+++ b/tests/tests/opengl/src/android/opengl/cts/Shaders.java
@@ -54,4 +54,40 @@
+ " gl_FragColor = vec4 (ct, 1.0); \n"
+ "} \n";
+ public static String errorcompile_frag =
+ "#ifdef GL_ES \n"
+ + "precision mediump float; \n"
+ + "#endif \n"
+ + "uniform float mortarThickness; \n"
+ + "uniform vec3 brickColor; \n"
+ + "uniform vec3 mortarColor; \n"
+
+ + "uniform float brickMortarWidth; \n"
+ + "uniform float brickMortarHeight; \n"
+ + "uniform float mhf; \n"
+
+ + "varying vec3 Position; \n"
+ + "varying float lightIntensity; \n"
+ + "\n"
+ + "void main (void){ \n"
+ + " vec3 ct; \n"
+ + " float ss, tt, w, h; \n"
+ + ""
+ + " vec3 pos = Position; \n"
+ + ""
+ + " ss = pos.x / brickMortarWidth; \n"
+ + " tt = pos.z / brickMortarHeight; \n"
+ + " if (fract (tt * 0.5) > 0.5) \n"
+ + " ss += 0.5; \n"
+
+ + " ss = fract (ss); \n"
+ + " tt = fract (tt); \n"
+
+ + " w = step (mwf, ss) - step (1.0 - mwf, ss); \n"
+ + " h = step (mhf, tt) - step (1.0 - mhf, tt); \n"
+
+ + " ct = clamp(mix (mortarColor, brickColor, w * h) * lightIntensity, 0.0, 1.0); \n"
+
+ + " gl_FragColor = vec4 (ct, 1); \n"
+ + "} \n";
}
diff --git a/tests/tests/os/src/android/os/cts/BuildTest.java b/tests/tests/os/src/android/os/cts/BuildTest.java
index a0446bf..a0f7d5b 100644
--- a/tests/tests/os/src/android/os/cts/BuildTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildTest.java
@@ -19,6 +19,7 @@
import android.os.Build;
import android.os.SystemProperties;
+import android.platform.test.annotations.RestrictedBuildTest;
import dalvik.system.VMRuntime;
@@ -232,6 +233,7 @@
* Note: This test will fail on userdebug / eng devices, but should pass
* on production (user) builds.
*/
+ @RestrictedBuildTest
public void testIsSecureUserBuild() throws IOException {
assertEquals("Must be a user build", "user", Build.TYPE);
assertProperty("Must be a non-debuggable build", RO_DEBUGGABLE, "0");
diff --git a/tests/tests/os/src/android/os/cts/ParcelTest.java b/tests/tests/os/src/android/os/cts/ParcelTest.java
index 5b7b187..305f0c8 100644
--- a/tests/tests/os/src/android/os/cts/ParcelTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelTest.java
@@ -3085,4 +3085,77 @@
assertFalse(doesNotImplementParcelableInitializerHasRun);
}
+
+ public static class SimpleParcelable implements Parcelable {
+ private final int value;
+
+ public SimpleParcelable(int value) {
+ this.value = value;
+ }
+
+ private SimpleParcelable(Parcel in) {
+ this.value = in.readInt();
+ }
+
+ public int getValue() {
+ return value;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeInt(value);
+ }
+
+ public static Parcelable.Creator<SimpleParcelable> CREATOR =
+ new Parcelable.Creator<SimpleParcelable>() {
+
+ @Override
+ public SimpleParcelable createFromParcel(Parcel source) {
+ return new SimpleParcelable(source);
+ }
+
+ @Override
+ public SimpleParcelable[] newArray(int size) {
+ return new SimpleParcelable[size];
+ }
+ };
+ }
+
+ public void testReadWriteParcellableList() {
+ Parcel parcel = Parcel.obtain();
+
+ ArrayList<SimpleParcelable> list = new ArrayList<>();
+ list.add(new SimpleParcelable(57));
+
+ // Writing a |null| list to a parcel should work, and reading it back
+ // from a parcel should clear the target list.
+ parcel.writeParcelableList(null, 0);
+ parcel.setDataPosition(0);
+ parcel.readParcelableList(list, SimpleParcelable.class.getClassLoader());
+ assertEquals(0, list.size());
+
+ list.clear();
+ list.add(new SimpleParcelable(42));
+ list.add(new SimpleParcelable(56));
+
+ parcel.setDataPosition(0);
+ parcel.writeParcelableList(list, 0);
+
+ // Populate the list with a value, we will later assert that the
+ // value has been removed.
+ list.clear();
+ list.add(new SimpleParcelable(100));
+
+ parcel.setDataPosition(0);
+ parcel.readParcelableList(list, SimpleParcelable.class.getClassLoader());
+
+ assertEquals(2, list.size());
+ assertEquals(42, list.get(0).getValue());
+ assertEquals(56, list.get(1).getValue());
+ }
}
diff --git a/tests/tests/permission2/Android.mk b/tests/tests/permission2/Android.mk
index 0be31be..dda9553 100755
--- a/tests/tests/permission2/Android.mk
+++ b/tests/tests/permission2/Android.mk
@@ -26,7 +26,7 @@
LOCAL_JAVA_LIBRARIES := telephony-common
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index 8c68635..ca7a698 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -741,6 +741,15 @@
android:permissionGroup="android.permission-group.PHONE"
android:label="@string/permlab_readPhoneState"
android:description="@string/permdesc_readPhoneState"
+ android:protectionLevel="dangerous" />
+
+ <!-- Allows read access to the device's phone number. This is a subset of the capabilities
+ granted by {@link #READ_PHONE_STATE} but is exposed to ephemeral applications.
+ <p>Protection level: dangerous-->
+ <permission android:name="android.permission.READ_PHONE_NUMBER"
+ android:permissionGroup="android.permission-group.PHONE"
+ android:label="@string/permlab_readPhoneNumber"
+ android:description="@string/permdesc_readPhoneNumber"
android:protectionLevel="dangerous|ephemeral" />
<!-- Allows an application to initiate a phone call without going through
@@ -900,7 +909,7 @@
android:permissionGroup="android.permission-group.CAMERA"
android:label="@string/permlab_camera"
android:description="@string/permdesc_camera"
- android:protectionLevel="dangerous" />
+ android:protectionLevel="dangerous|ephemeral" />
<!-- ====================================================================== -->
@@ -1148,7 +1157,7 @@
<permission android:name="android.permission.ACCESS_NETWORK_STATE"
android:description="@string/permdesc_accessNetworkState"
android:label="@string/permlab_accessNetworkState"
- android:protectionLevel="normal" />
+ android:protectionLevel="normal|ephemeral" />
<!-- Allows applications to access information about Wi-Fi networks.
<p>Protection level: normal
diff --git a/tests/tests/permission2/src/android/permission2/cts/NoReceiveSmsPermissionTest.java b/tests/tests/permission2/src/android/permission2/cts/NoReceiveSmsPermissionTest.java
index d0cafe9..5699d88 100644
--- a/tests/tests/permission2/src/android/permission2/cts/NoReceiveSmsPermissionTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/NoReceiveSmsPermissionTest.java
@@ -42,6 +42,9 @@
"com.android.cts.permission.sms.MESSAGE_STATUS_RECEIVED_ACTION";
private static final String MESSAGE_SENT_ACTION =
"com.android.cts.permission.sms.MESSAGE_SENT";
+ private static final String APP_SPECIFIC_SMS_RECEIVED_ACTION =
+ "com.android.cts.permission.sms.APP_SPECIFIC_SMS_RECEIVED";
+
private static final String LOG_TAG = "NoReceiveSmsPermissionTest";
@@ -70,7 +73,7 @@
filter.addAction(MESSAGE_STATUS_RECEIVED_ACTION);
getContext().registerReceiver(receiver, filter);
- sendSMSToSelf();
+ sendSMSToSelf("test");
synchronized(receiver) {
try {
receiver.wait(WAIT_TIME);
@@ -84,7 +87,46 @@
assertFalse("Sms received without proper permissions", receiver.isSmsReceived());
}
- private void sendSMSToSelf() {
+ /**
+ * Verify that without {@link android.Manifest.permission#RECEIVE_SMS} that an SMS sent
+ * containing a nonce from {@link SmsManager#createAppSpecificSmsToken} is delivered
+ * to the app.
+ */
+ public void testAppSpecificSmsToken() {
+ PackageManager packageManager = mContext.getPackageManager();
+ if (!packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+ return;
+ }
+
+ AppSpecificSmsReceiver receiver = new AppSpecificSmsReceiver();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(TELEPHONY_SMS_RECEIVED);
+ filter.addAction(MESSAGE_SENT_ACTION);
+ filter.addAction(MESSAGE_STATUS_RECEIVED_ACTION);
+ filter.addAction(APP_SPECIFIC_SMS_RECEIVED_ACTION);
+ getContext().registerReceiver(receiver, filter);
+
+ PendingIntent receivedIntent = PendingIntent.getBroadcast(getContext(), 0,
+ new Intent(APP_SPECIFIC_SMS_RECEIVED_ACTION), PendingIntent.FLAG_ONE_SHOT);
+
+ String token = SmsManager.getDefault().createAppSpecificSmsToken(receivedIntent);
+ String message = "test message, token=" + token;
+ sendSMSToSelf(message);
+ synchronized(receiver) {
+ try {
+ receiver.wait(WAIT_TIME);
+ } catch (InterruptedException e) {
+ Log.w(LOG_TAG, "wait for sms interrupted");
+ }
+ }
+
+ assertTrue("[RERUN] Sms not sent successfully. Check signal.",
+ receiver.isMessageSent());
+ assertFalse("Sms received without proper permissions", receiver.isSmsReceived());
+ assertTrue("App specific SMS intent not triggered", receiver.isAppSpecificSmsReceived());
+ }
+
+ private void sendSMSToSelf(String message) {
PendingIntent sentIntent = PendingIntent.getBroadcast(getContext(), 0,
new Intent(MESSAGE_SENT_ACTION), PendingIntent.FLAG_ONE_SHOT);
PendingIntent deliveryIntent = PendingIntent.getBroadcast(getContext(), 0,
@@ -98,7 +140,7 @@
TextUtils.isEmpty(currentNumber));
Log.i(LOG_TAG, String.format("Sending SMS to self: %s", currentNumber));
- sendSms(currentNumber, "test message", sentIntent, deliveryIntent);
+ sendSms(currentNumber, message, sentIntent, deliveryIntent);
}
protected void sendSms(String currentNumber, String text, PendingIntent sentIntent,
@@ -180,4 +222,21 @@
return "unknown";
}
}
+
+ public class AppSpecificSmsReceiver extends IllegalSmsReceiver {
+ private boolean mAppSpecificSmsReceived = false;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (APP_SPECIFIC_SMS_RECEIVED_ACTION.equals(intent.getAction())) {
+ mAppSpecificSmsReceived = true;
+ } else {
+ super.onReceive(context, intent);
+ }
+ }
+
+ public boolean isAppSpecificSmsReceived() {
+ return mAppSpecificSmsReceived;
+ }
+ }
}
diff --git a/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java b/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java
new file mode 100644
index 0000000..8ae0692
--- /dev/null
+++ b/tests/tests/permission2/src/android/permission2/cts/PrivappPermissionsTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.permission2.cts;
+
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
+import android.cts.util.SystemUtil;
+import android.support.test.InstrumentationRegistry;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import static android.content.pm.PackageManager.GET_PERMISSIONS;
+
+/**
+ * Tests enforcement of signature|privileged permission whitelist:
+ * <ul>
+ * <li>Report what is granted into the CTS log
+ * <li>Ensure all priv permissions are exclusively granted to applications declared in
+ * <privapp-permissions>
+ * </ul>
+ */
+public class PrivappPermissionsTest extends AndroidTestCase {
+
+ private static final String TAG = "PrivappPermissionsTest";
+
+ private static final String PLATFORM_PACKAGE_NAME = "android";
+
+ public void testPrivappPermissionsEnforcement() throws Exception {
+ Set<String> platformPrivPermissions = new HashSet<>();
+ PackageManager pm = getContext().getPackageManager();
+ PackageInfo platformPackage = pm.getPackageInfo(PLATFORM_PACKAGE_NAME,
+ PackageManager.GET_PERMISSIONS);
+
+ for (PermissionInfo permission : platformPackage.permissions) {
+ int protectionLevel = permission.protectionLevel;
+ if ((protectionLevel & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
+ platformPrivPermissions.add(permission.name);
+ }
+ }
+
+ List<PackageInfo> installedPackages = pm
+ .getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES | GET_PERMISSIONS);
+
+ for (PackageInfo pkg : installedPackages) {
+ Set<String> requestedPrivPermissions = new TreeSet<>();
+ Set<String> grantedPrivPermissions = new TreeSet<>();
+ String[] requestedPermissions = pkg.requestedPermissions;
+ if (!pkg.applicationInfo.isPrivilegedApp()
+ || PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
+ continue;
+ }
+ if (requestedPermissions == null || requestedPermissions.length == 0) {
+ continue;
+ }
+ // Collect 2 sets: requestedPermissions and grantedPrivPermissions
+ for (int i = 0; i < requestedPermissions.length; i++) {
+ String permission = requestedPermissions[i];
+ if (platformPrivPermissions.contains(permission)) {
+ requestedPrivPermissions.add(permission);
+ if ((pkg.requestedPermissionsFlags[i]
+ & PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
+ grantedPrivPermissions.add(permission);
+ }
+ }
+ }
+ // If an app is requesting any privileged permissions, log the details and verify
+ // that granted permissions are whitelisted
+ if (!requestedPrivPermissions.isEmpty()) {
+ Set<String> notGranted = new TreeSet<>(requestedPrivPermissions);
+ notGranted.removeAll(grantedPrivPermissions);
+ Set<String> whitelist = getPrivAppPermissions(pkg.packageName);
+ Log.i(TAG, "Application " + pkg.packageName + ". Requested permissions: "
+ + requestedPrivPermissions + ". Granted permissions: "
+ + grantedPrivPermissions + ". Not granted: " + notGranted + " Whitelisted: "
+ + whitelist);
+
+ Set<String> grantedNotInWhitelist = new TreeSet<>(grantedPrivPermissions);
+ grantedNotInWhitelist.removeAll(whitelist);
+
+ assertTrue("Not whitelisted permissions are granted for package "
+ + pkg.packageName + ": " + grantedNotInWhitelist,
+ grantedNotInWhitelist.isEmpty());
+ }
+
+ }
+ }
+
+ private Set<String> getPrivAppPermissions(String packageName) throws IOException {
+ String output = SystemUtil.runShellCommand(
+ InstrumentationRegistry.getInstrumentation(),
+ "cmd package get-privapp-permissions " + packageName).trim();
+ if (output.startsWith("{") && output.endsWith("}")) {
+ String[] split = output.substring(1, output.length() - 1).split("\\s*,\\s*");
+ return new LinkedHashSet<>(Arrays.asList(split));
+ }
+ return Collections.emptySet();
+ }
+
+}
diff --git a/tests/tests/preference2/Android.mk b/tests/tests/preference2/Android.mk
index 2fd94a6..40346d4 100644
--- a/tests/tests/preference2/Android.mk
+++ b/tests/tests/preference2/Android.mk
@@ -25,7 +25,9 @@
# Tag this module as a cts test artifact
LOCAL_COMPATIBILITY_SUITE := cts
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ ctstestrunner \
+ mockito-target-minus-junit4 \
LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceDataStoreTest.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceDataStoreTest.java
new file mode 100644
index 0000000..5c3b181
--- /dev/null
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceDataStoreTest.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.preference2.cts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.mockito.AdditionalMatchers.or;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyFloat;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import android.content.Context;
+import android.preference.Preference;
+import android.preference.PreferenceDataStore;
+import android.preference.PreferenceScreen;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class PreferenceDataStoreTest {
+
+ private PreferenceWrapper mPreference;
+ private PreferenceDataStore mDataStore;
+
+ private static final String KEY = "TestPrefKey";
+ private static final String TEST_STR = "Test";
+
+ @Rule
+ public ActivityTestRule<PreferenceFragmentActivity> mActivityRule =
+ new ActivityTestRule<>(PreferenceFragmentActivity.class);
+
+
+ @Before
+ public void setup() {
+ PreferenceFragmentActivity activity = mActivityRule.getActivity();
+ mPreference = new PreferenceWrapper(activity);
+ mPreference.setKey(KEY);
+
+ // Assign the Preference to the PreferenceFragment.
+ PreferenceScreen screen =
+ activity.prefFragment.getPreferenceManager().createPreferenceScreen(activity);
+ screen.addPreference(mPreference);
+
+ mDataStore = mock(PreferenceDataStore.class);
+ }
+
+ @Test
+ public void testPutStringWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ putStringTestCommon();
+ }
+
+ @Test
+ public void testPutStringWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ putStringTestCommon();
+ }
+
+ @Test
+ public void testGetStringWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ mPreference.getString(TEST_STR);
+ verify(mDataStore, atLeastOnce()).getString(eq(KEY), eq(TEST_STR));
+ }
+
+ @Test
+ public void testGetStringWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ mPreference.getString(TEST_STR);
+ verify(mDataStore, atLeastOnce()).getString(eq(KEY), eq(TEST_STR));
+ }
+
+ @Test
+ public void testPutStringSetWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ putStringSetTestCommon();
+ }
+
+ @Test
+ public void testPutStringSetWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ putStringSetTestCommon();
+ }
+
+ @Test
+ public void testGetStringSetWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ Set<String> testSet = new HashSet<>();
+ mPreference.getStringSet(testSet);
+ verify(mDataStore, atLeastOnce()).getStringSet(eq(KEY), eq(testSet));
+ }
+
+ @Test
+ public void testGetStringSetWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ Set<String> testSet = new HashSet<>();
+ mPreference.getStringSet(testSet);
+ verify(mDataStore, atLeastOnce()).getStringSet(eq(KEY), eq(testSet));
+ }
+
+ @Test
+ public void testPutIntWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ putIntTestCommon();
+ }
+
+ @Test
+ public void testPutIntWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ putIntTestCommon();
+ }
+
+ @Test
+ public void testGetIntWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ mPreference.getInt(1);
+ verify(mDataStore, atLeastOnce()).getInt(eq(KEY), eq(1));
+ }
+
+ @Test
+ public void testGetIntWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ mPreference.getInt(1);
+ verify(mDataStore, atLeastOnce()).getInt(eq(KEY), eq(1));
+ }
+
+ @Test
+ public void testPutLongWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ putLongTestCommon();
+ }
+
+ @Test
+ public void testPutLongWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ putLongTestCommon();
+ }
+
+ @Test
+ public void testGetLongWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ mPreference.getLong(1L);
+ verify(mDataStore, atLeastOnce()).getLong(eq(KEY), eq(1L));
+ }
+
+ @Test
+ public void testGetLongWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ mPreference.getLong(1L);
+ verify(mDataStore, atLeastOnce()).getLong(eq(KEY), eq(1L));
+ }
+
+ @Test
+ public void testPutFloatWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ putFloatTestCommon();
+ }
+
+ @Test
+ public void testPutFloatWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ putFloatTestCommon();
+ }
+
+ @Test
+ public void testGetFloatWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ mPreference.getFloat(1f);
+ verify(mDataStore, atLeastOnce()).getFloat(eq(KEY), eq(1f));
+ }
+
+ @Test
+ public void testGetFloatWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ mPreference.getFloat(1f);
+ verify(mDataStore, atLeastOnce()).getFloat(eq(KEY), eq(1f));
+ }
+
+ @Test
+ public void testPutBooleanWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ putBooleanTestCommon();
+ }
+
+ @Test
+ public void testPutBooleanWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ putBooleanTestCommon();
+ }
+
+ @Test
+ public void testGetBooleanWithDataStoreOnPref() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ mPreference.getBoolean(true);
+ verify(mDataStore, atLeastOnce()).getBoolean(eq(KEY), eq(true));
+ }
+
+ @Test
+ public void testGetBooleanWithDataStoreOnMgr() {
+ mPreference.getPreferenceManager().setPreferenceDataStore(mDataStore);
+ mPreference.getBoolean(true);
+ verify(mDataStore, atLeastOnce()).getBoolean(eq(KEY), eq(true));
+ }
+
+ @Test
+ public void testDataStoresHierarchy() {
+ mPreference.setPreferenceDataStore(mDataStore);
+ PreferenceDataStore secondaryDataStore = mock(PreferenceDataStore.class);
+ mPreference.getPreferenceManager().setPreferenceDataStore(secondaryDataStore);
+ mPreference.putString(TEST_STR);
+
+ // Check that the Preference returns the correct data store.
+ assertEquals(mDataStore, mPreference.getPreferenceDataStore());
+
+ // Check that the secondary data store assigned to the manager was NOT used.
+ verifyZeroInteractions(secondaryDataStore);
+
+ // Check that the primary data store assigned directly to the preference was used.
+ verify(mDataStore, atLeast(0)).getString(eq(KEY), anyString());
+ }
+
+ private void putStringTestCommon() {
+ mPreference.putString(TEST_STR);
+
+ verify(mDataStore, atLeast(0)).getString(eq(KEY), anyString());
+ verify(mDataStore, atLeastOnce()).putString(eq(KEY), anyString());
+ verifyNoMoreInteractions(mDataStore);
+
+ // Test that the value was NOT propagated to SharedPreferences.
+ assertNull(mPreference.getSharedPreferences().getString(KEY, null));
+ }
+
+ private void putStringSetTestCommon() {
+ Set<String> testSet = new HashSet<>();
+ testSet.add(TEST_STR);
+ mPreference.putStringSet(testSet);
+
+ verify(mDataStore, atLeast(0)).getStringSet(eq(KEY), or(isNull(Set.class), any()));
+ verify(mDataStore, atLeastOnce()).putStringSet(eq(KEY), or(isNull(Set.class), any()));
+ verifyNoMoreInteractions(mDataStore);
+
+ // Test that the value was NOT propagated to SharedPreferences.
+ assertNull(mPreference.getSharedPreferences().getStringSet(KEY, null));
+ }
+
+ private void putIntTestCommon() {
+ mPreference.putInt(1);
+
+ verify(mDataStore, atLeast(0)).getInt(eq(KEY), anyInt());
+ verify(mDataStore, atLeastOnce()).putInt(eq(KEY), anyInt());
+ verifyNoMoreInteractions(mDataStore);
+
+ // Test that the value was NOT propagated to SharedPreferences.
+ assertEquals(-1, mPreference.getSharedPreferences().getInt(KEY, -1));
+ }
+
+ private void putLongTestCommon() {
+ mPreference.putLong(1L);
+
+ verify(mDataStore, atLeast(0)).getLong(eq(KEY), anyLong());
+ verify(mDataStore, atLeastOnce()).putLong(eq(KEY), anyLong());
+ verifyNoMoreInteractions(mDataStore);
+
+ // Test that the value was NOT propagated to SharedPreferences.
+ assertEquals(-1, mPreference.getSharedPreferences().getLong(KEY, -1L));
+ }
+
+ private void putFloatTestCommon() {
+ mPreference.putFloat(1f);
+
+ verify(mDataStore, atLeast(0)).getFloat(eq(KEY), anyFloat());
+ verify(mDataStore, atLeastOnce()).putFloat(eq(KEY), anyFloat());
+ verifyNoMoreInteractions(mDataStore);
+
+ // Test that the value was NOT propagated to SharedPreferences.
+ assertEquals(-1, mPreference.getSharedPreferences().getFloat(KEY, -1f), 0.1f /* epsilon */);
+ }
+
+ private void putBooleanTestCommon() {
+ mPreference.putBoolean(true);
+
+ verify(mDataStore, atLeast(0)).getBoolean(eq(KEY), anyBoolean());
+ verify(mDataStore, atLeastOnce()).putBoolean(eq(KEY), anyBoolean());
+ verifyNoMoreInteractions(mDataStore);
+
+ // Test that the value was NOT propagated to SharedPreferences.
+ assertEquals(false, mPreference.getSharedPreferences().getBoolean(KEY, false));
+ }
+
+ /**
+ * Wrapper to allow to easily call protected methods.
+ */
+ private static class PreferenceWrapper extends Preference {
+
+ PreferenceWrapper(Context context) {
+ super(context);
+ }
+
+ void putString(String value) {
+ persistString(value);
+ }
+
+ String getString(String defaultValue) {
+ return getPersistedString(defaultValue);
+ }
+
+ void putStringSet(Set<String> values) {
+ persistStringSet(values);
+ }
+
+ Set<String> getStringSet(Set<String> defaultValues) {
+ return getPersistedStringSet(defaultValues);
+ }
+
+ void putInt(int value) {
+ persistInt(value);
+ }
+
+ int getInt(int defaultValue) {
+ return getPersistedInt(defaultValue);
+ }
+
+ void putLong(long value) {
+ persistLong(value);
+ }
+
+ long getLong(long defaultValue) {
+ return getPersistedLong(defaultValue);
+ }
+
+ void putFloat(float value) {
+ persistFloat(value);
+ }
+
+ float getFloat(float defaultValue) {
+ return getPersistedFloat(defaultValue);
+ }
+
+ void putBoolean(boolean value) {
+ persistBoolean(value);
+ }
+
+ boolean getBoolean(boolean defaultValue) {
+ return getPersistedBoolean(defaultValue);
+ }
+ }
+
+}
diff --git a/tests/tests/preference2/src/android/preference2/cts/PreferenceFragmentActivity.java b/tests/tests/preference2/src/android/preference2/cts/PreferenceFragmentActivity.java
index 4f12d17..8b7a6d9 100644
--- a/tests/tests/preference2/src/android/preference2/cts/PreferenceFragmentActivity.java
+++ b/tests/tests/preference2/src/android/preference2/cts/PreferenceFragmentActivity.java
@@ -13,12 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
- package android.preference2.cts;
+package android.preference2.cts;
import android.app.Activity;
import android.app.FragmentTransaction;
import android.os.Bundle;
+import android.preference.Preference;
import android.preference.PreferenceFragment;
+import android.preference.PreferenceScreen;
/**
* Demonstration of PreferenceFragment, showing a single fragment in an
@@ -31,14 +33,15 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- prefFragment = new PrefFragment();
- FragmentTransaction transaction = getFragmentManager().beginTransaction()
- .replace(android.R.id.content, prefFragment, PrefFragment.TAG);
- transaction.commit();
+ prefFragment = new PrefFragment();
+ getFragmentManager()
+ .beginTransaction()
+ .replace(android.R.id.content, prefFragment, PrefFragment.TAG)
+ .commit();
}
- public class PrefFragment extends PreferenceFragment {
+ public static class PrefFragment extends PreferenceFragment {
public static final String TAG = "Pref-1";
public PrefFragment() {
diff --git a/tests/tests/proto/src/android/util/proto/cts/ProtoOutputStreamObjectTest.java b/tests/tests/proto/src/android/util/proto/cts/ProtoOutputStreamObjectTest.java
index e673bb0..fb23607 100644
--- a/tests/tests/proto/src/android/util/proto/cts/ProtoOutputStreamObjectTest.java
+++ b/tests/tests/proto/src/android/util/proto/cts/ProtoOutputStreamObjectTest.java
@@ -779,4 +779,115 @@
// good
}
}
+
+ /**
+ * Test writeObject, which takes a pre-encoded and compacted protobuf object and writes it into
+ * a field.
+ */
+ public void testWriteObject() {
+ byte[] innerRaw = new byte[] {
+ // varint 1 -> 42
+ (byte)0x08,
+ (byte)0xd0, (byte)0x02,
+ // string 2 -> "ab"
+ (byte)0x12,
+ (byte)0x02,
+ (byte)0x62, (byte)0x63,
+ // object 3 -> ...
+ (byte)0x1a,
+ (byte)0x4,
+ // varint 4 -> 0
+ (byte)0x20,
+ (byte)0x00,
+ // varint 4 --> 1
+ (byte)0x20,
+ (byte)0x01,
+ };
+
+ final ProtoOutputStream po = new ProtoOutputStream();
+ po.writeObject(ProtoOutputStream.makeFieldId(10,
+ ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_OBJECT),
+ innerRaw);
+
+ final byte[] result = po.getBytes();
+ final byte[] expected = new byte[2 + innerRaw.length];
+ expected[0] = (byte)0x52;
+ expected[1] = (byte)0x0d;
+ System.arraycopy(innerRaw, 0, expected, 2, innerRaw.length);
+
+ Assert.assertArrayEquals(expected, result);
+ }
+
+ /**
+ * Test writeObject, which takes a pre-encoded and compacted protobuf object and writes it into
+ * a field.
+ */
+ public void testWriteObjectEmpty() {
+ byte[] innerRaw = new byte[0];
+
+ final ProtoOutputStream po = new ProtoOutputStream();
+ po.writeObject(ProtoOutputStream.makeFieldId(10,
+ ProtoOutputStream.FIELD_COUNT_SINGLE | ProtoOutputStream.FIELD_TYPE_OBJECT),
+ innerRaw);
+
+ final byte[] result = po.getBytes();
+
+ Assert.assertEquals(0, result.length);
+ }
+
+ /**
+ * Test writeObject, which takes a pre-encoded and compacted protobuf object and writes it into
+ * a field.
+ */
+ public void testWriteObjectRepeated() {
+ byte[] innerRaw = new byte[] {
+ // varint 1 -> 42
+ (byte)0x08,
+ (byte)0xd0, (byte)0x02,
+ // string 2 -> "ab"
+ (byte)0x12,
+ (byte)0x02,
+ (byte)0x62, (byte)0x63,
+ // object 3 -> ...
+ (byte)0x1a,
+ (byte)0x4,
+ // varint 4 -> 0
+ (byte)0x20,
+ (byte)0x00,
+ // varint 4 --> 1
+ (byte)0x20,
+ (byte)0x01,
+ };
+
+ final ProtoOutputStream po = new ProtoOutputStream();
+ po.writeRepeatedObject(ProtoOutputStream.makeFieldId(10,
+ ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_OBJECT),
+ innerRaw);
+
+ final byte[] result = po.getBytes();
+ final byte[] expected = new byte[2 + innerRaw.length];
+ expected[0] = (byte)0x52;
+ expected[1] = (byte)0x0d;
+ System.arraycopy(innerRaw, 0, expected, 2, innerRaw.length);
+
+ Assert.assertArrayEquals(expected, result);
+ }
+
+ /**
+ * Test writeObject, which takes a pre-encoded and compacted protobuf object and writes it into
+ * a field.
+ */
+ public void testWriteObjectRepeatedEmpty() {
+ byte[] innerRaw = new byte[0];
+
+ final ProtoOutputStream po = new ProtoOutputStream();
+ po.writeRepeatedObject(ProtoOutputStream.makeFieldId(10,
+ ProtoOutputStream.FIELD_COUNT_REPEATED | ProtoOutputStream.FIELD_TYPE_OBJECT),
+ innerRaw);
+
+ Assert.assertArrayEquals(new byte[] {
+ (byte)0x52,
+ (byte)0x00
+ }, po.getBytes());
+ }
}
diff --git a/tests/tests/proto/src/android/util/proto/cts/ProtoOutputStreamSwitchedWriteTest.java b/tests/tests/proto/src/android/util/proto/cts/ProtoOutputStreamSwitchedWriteTest.java
new file mode 100644
index 0000000..9052755
--- /dev/null
+++ b/tests/tests/proto/src/android/util/proto/cts/ProtoOutputStreamSwitchedWriteTest.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.util.proto.cts;
+
+import android.util.Log;
+import android.util.proto.ProtoOutputStream;
+import static android.util.proto.ProtoOutputStream.*;
+
+import com.google.protobuf.nano.MessageNano;
+import junit.framework.TestCase;
+import org.junit.Assert;
+
+import java.util.HashMap;
+import java.util.ArrayList;
+
+/**
+ * Tests that the write() functions produce the same values as their typed counterparts.
+ */
+public class ProtoOutputStreamSwitchedWriteTest extends TestCase {
+ private static final String TAG = "ProtoOutputStreamSwitchedWriteTest";
+
+ public static abstract class WriteTester {
+ public final String name;
+
+ public WriteTester(String n) {
+ name = n;
+ }
+
+ abstract void write(Number val, long fieldId, ProtoOutputStream po);
+ }
+
+ private static final HashMap<Long,WriteTester> TYPED = new HashMap<Long,WriteTester>();
+ private static final ArrayList<WriteTester> SWITCHED = new ArrayList<WriteTester>();
+
+ static {
+ TYPED.put(FIELD_TYPE_DOUBLE | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_DOUBLE | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeDouble(fieldId, val.doubleValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_FLOAT | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_FLOAT | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeFloat(fieldId, val.floatValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_INT32 | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_INT32 | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeInt32(fieldId, val.intValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_INT64 | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_INT64 | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeInt64(fieldId, val.longValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_UINT32 | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_UINT32 | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeUInt32(fieldId, val.intValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_UINT64 | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_UINT64 | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeUInt64(fieldId, val.longValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_SINT32 | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_SINT32 | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeSInt32(fieldId, val.intValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_SINT64 | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_SINT64 | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeSInt64(fieldId, val.longValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_FIXED32 | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_FIXED32 | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeFixed32(fieldId, val.intValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_FIXED64 | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_FIXED64 | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeFixed64(fieldId, val.longValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_SFIXED32 | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_SFIXED32 | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeSFixed32(fieldId, val.intValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_SFIXED64 | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_SFIXED64 | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeSFixed64(fieldId, val.longValue());
+ }
+ });
+ TYPED.put(FIELD_TYPE_BOOL | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_BOOL | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeBool(fieldId, val.longValue() != 0);
+ }
+ });
+ TYPED.put(FIELD_TYPE_ENUM | FIELD_COUNT_SINGLE,
+ new WriteTester("FIELD_TYPE_ENUM | FIELD_COUNT_SINGLE") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.writeEnum(fieldId, val.intValue());
+ }
+ });
+
+ SWITCHED.add(new WriteTester("write(long, double)") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.write(fieldId, val.doubleValue());
+ }
+ });
+ SWITCHED.add(new WriteTester("write(long, float)") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.write(fieldId, val.floatValue());
+ }
+ });
+ SWITCHED.add(new WriteTester("write(long, int)") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.write(fieldId, val.intValue());
+ }
+ });
+ SWITCHED.add(new WriteTester("write(long, long)") {
+ @Override
+ public void write(Number val, long fieldId, ProtoOutputStream po) {
+ po.write(fieldId, val.longValue());
+ }
+ });
+ }
+
+ private static void testAWrite(Number val, long fieldId,
+ WriteTester typed, WriteTester switched) {
+ final ProtoOutputStream switchedPo = new ProtoOutputStream();
+ final ProtoOutputStream typedPo = new ProtoOutputStream();
+
+ typed.write(val, fieldId, typedPo);
+ switched.write(val, fieldId, switchedPo);
+
+ final byte[] switchedResult = switchedPo.getBytes();
+ final byte[] typedResult = typedPo.getBytes();
+
+ try {
+ Assert.assertArrayEquals(typedResult, switchedResult);
+ } catch (Throwable ex) {
+ throw new RuntimeException("Test for " + typed.name + " and "
+ + switched.name + " value=" + val + " (" + val.getClass().getSimpleName()
+ + ") failed: " + ex.getMessage(), ex);
+ }
+ }
+
+ public static void testWrites(Number val) {
+ for (HashMap.Entry<Long,WriteTester> entry: TYPED.entrySet()) {
+ final long fieldId = ((long)entry.getKey()) | 1;
+ final WriteTester typed = entry.getValue();
+
+ for (WriteTester switched: SWITCHED) {
+ testAWrite(val, fieldId, typed, switched);
+ }
+ }
+ }
+/**
+ * Test double
+ */
+ public void testWriteDouble() {
+ testWrites(new Double(0));
+ testWrites(new Double(-1));
+ testWrites(new Double(1));
+ testWrites(new Double(100));
+ }
+
+ /**
+ * Test float
+ */
+ public void testWriteFloat() {
+ testWrites(new Float(0));
+ testWrites(new Float(-1));
+ testWrites(new Float(1));
+ testWrites(new Float(100));
+ }
+
+ /**
+ * Test int
+ */
+ public void testWriteInteger() {
+ testWrites(new Integer(0));
+ testWrites(new Integer(-1));
+ testWrites(new Integer(1));
+ testWrites(new Integer(100));
+ }
+
+ /**
+ * Test long
+ */
+ public void testWriteLong() {
+ testWrites(new Long(0));
+ testWrites(new Long(-1));
+ testWrites(new Long(1));
+ testWrites(new Long(100));
+ }
+
+ /**
+ * Test single strings
+ */
+ public void testWriteString() {
+ final ProtoOutputStream typedPo = new ProtoOutputStream();
+ final ProtoOutputStream switchedPo = new ProtoOutputStream();
+
+ testString(1, "", typedPo, switchedPo);
+ testString(2, null, typedPo, switchedPo);
+ testString(3, "ABCD", typedPo, switchedPo);
+
+ final byte[] typedResult = typedPo.getBytes();
+ final byte[] switchedResult = switchedPo.getBytes();
+
+ Assert.assertArrayEquals(typedResult, switchedResult);
+ }
+
+ private void testString(int id, String val,
+ ProtoOutputStream typed, ProtoOutputStream switched) {
+ switched.write(FIELD_TYPE_STRING | FIELD_COUNT_SINGLE | id, val);
+ typed.writeString(FIELD_TYPE_STRING | FIELD_COUNT_SINGLE | id, val);
+ }
+
+ /**
+ * Test repeated strings
+ */
+ public void testWriteRepeatedString() {
+ final ProtoOutputStream typedPo = new ProtoOutputStream();
+ final ProtoOutputStream switchedPo = new ProtoOutputStream();
+
+ testRepeatedString(1, "", typedPo, switchedPo);
+ testRepeatedString(2, null, typedPo, switchedPo);
+ testRepeatedString(3, "ABCD", typedPo, switchedPo);
+
+ final byte[] typedResult = typedPo.getBytes();
+ final byte[] switchedResult = switchedPo.getBytes();
+
+ Assert.assertArrayEquals(typedResult, switchedResult);
+ }
+
+ private void testRepeatedString(int id, String val,
+ ProtoOutputStream typed, ProtoOutputStream switched) {
+ switched.write(FIELD_TYPE_STRING | FIELD_COUNT_REPEATED | id, val);
+ typed.writeRepeatedString(FIELD_TYPE_STRING | FIELD_COUNT_REPEATED | id, val);
+ }
+
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_DataUsageTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataUsageTest.java
index 6ffa0cb..367ac30 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_DataUsageTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataUsageTest.java
@@ -182,7 +182,7 @@
// Also make sure the rounded value is used in 'where' too.
assertEquals("Query should match", 1, DataUtil.queryById(mResolver, dataId, projection,
- Data.TIMES_USED + "=" + expectedValue, null).length);
+ "ifnull(" + Data.TIMES_USED + ",0)=" + expectedValue, null).length);
}
private void deleteDataUsage() {
diff --git a/tests/tests/security/src/android/security/cts/EffectBundleTest.java b/tests/tests/security/src/android/security/cts/EffectBundleTest.java
index 2fa4218..c844fbb 100644
--- a/tests/tests/security/src/android/security/cts/EffectBundleTest.java
+++ b/tests/tests/security/src/android/security/cts/EffectBundleTest.java
@@ -22,6 +22,8 @@
import android.test.InstrumentationTestCase;
import android.util.Log;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
@@ -102,7 +104,7 @@
Log.w(TAG,"Problem creating reply string.");
}
} else {
- for (int i = 0; i< reply.length; i++) {
+ for (int i = 0; i < reply.length; i++) {
assertEquals(String.format("getParam should not change reply at byte %d", i),
testValue, reply[i]);
}
@@ -134,6 +136,70 @@
}
}
+ //testing security bug: 32705438
+ public void testEqualizer_getParamFreqRangeCommand_short() throws Exception {
+ assertTrue("testEqualizer_getParamFreqRangeCommand_short did not complete successfully",
+ eqGetParamFreqRangeCommand(MEDIA_SHORT));
+ }
+
+ //testing security bug: 32703959
+ public void testEqualizer_getParamFreqRangeCommand_long() throws Exception {
+ assertTrue("testEqualizer_getParamFreqRangeCommand_long did not complete successfully",
+ eqGetParamFreqRangeCommand(MEDIA_LONG));
+ }
+
+ private boolean eqGetParamFreqRangeCommand(int media) {
+ MediaPlayer mp = null;
+ Equalizer eq = null;
+ boolean status = false;
+ try {
+ mp = MediaPlayer.create(getInstrumentation().getContext(), getMediaId(media));
+ eq = new Equalizer(0 /*priority*/, mp.getAudioSessionId());
+
+ short band = 2;
+ int intSize = 4; //bytes
+
+ //baseline
+ int cmdCode = 8; // EFFECT_CMD_GET_PARAM
+ byte command[] = concatArrays(/*status*/ intToByteArray(0),
+ /*psize*/ intToByteArray(2 * intSize),
+ /*vsize*/ intToByteArray(2 * intSize),
+ /*data[0]*/ intToByteArray(Equalizer.PARAM_BAND_FREQ_RANGE),
+ /*data[1]*/ intToByteArray((int) band));
+
+ byte reply[] = new byte[command.length];
+
+ AudioEffect af = eq;
+ Object o = AudioEffect.class.getDeclaredMethod("command", int.class, byte[].class,
+ byte[].class).invoke(af, cmdCode, command, reply);
+
+ int methodStatus = AudioEffect.ERROR;
+ if (o != null) {
+ methodStatus = Integer.valueOf(o.toString()).intValue();
+ }
+
+ assertTrue("Command expected to fail", methodStatus <= 0);
+ int sum = 0;
+ for (int i = 0; i < reply.length; i++) {
+ sum += Math.abs(reply[i]);
+ }
+
+ assertEquals("reply expected to be all zeros", sum, 0);
+ status = true;
+ } catch (Exception e) {
+ Log.w(TAG,"Problem testing eqGetParamFreqRangeCommand");
+ status = false;
+ } finally {
+ if (eq != null) {
+ eq.release();
+ }
+ if (mp != null) {
+ mp.release();
+ }
+ }
+ return status;
+ }
+
private boolean eqGetParam(int media, int command, int band, byte[] reply) {
MediaPlayer mp = null;
Equalizer eq = null;
@@ -240,4 +306,34 @@
return R.raw.onekhzsine_90sec;
}
}
+
+ private static byte[] intToByteArray(int value) {
+ ByteBuffer converter = ByteBuffer.allocate(4);
+ converter.order(ByteOrder.nativeOrder());
+ converter.putInt(value);
+ return converter.array();
+ }
+
+ private static byte[] shortToByteArray(short value) {
+ ByteBuffer converter = ByteBuffer.allocate(2);
+ converter.order(ByteOrder.nativeOrder());
+ short sValue = (short) value;
+ converter.putShort(sValue);
+ return converter.array();
+ }
+
+ private static byte[] concatArrays(byte[]... arrays) {
+ int len = 0;
+ for (byte[] a : arrays) {
+ len += a.length;
+ }
+ byte[] b = new byte[len];
+
+ int offs = 0;
+ for (byte[] a : arrays) {
+ System.arraycopy(a, 0, b, offs, a.length);
+ offs += a.length;
+ }
+ return b;
+ }
}
diff --git a/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java b/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java
index 147a5cd..a0d359f7 100644
--- a/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java
+++ b/tests/tests/security/src/android/security/cts/MediaServerCrashTest.java
@@ -17,6 +17,7 @@
package android.security.cts;
import android.content.res.AssetFileDescriptor;
+import android.cts.util.MediaUtils;
import android.drm.DrmConvertedStatus;
import android.drm.DrmManagerClient;
import android.media.MediaPlayer;
@@ -120,11 +121,16 @@
}
private void checkIfMediaServerDiedForDrm(int res) throws Exception {
- if (!convertDmToFl(res, mFlFilePath)) {
+ AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(res);
+ FileInputStream dmStream = afd.createInputStream();
+ RandomAccessFile flFile = new RandomAccessFile(mFlFilePath, "rw");
+ if (!MediaUtils.convertDmToFl(mContext, dmStream, flFile)) {
Log.w(TAG, "Can not convert dm to fl, skip checkIfMediaServerDiedForDrm");
mMediaPlayer.release();
return;
}
+ dmStream.close();
+ flFile.close();
Log.d(TAG, "intermediate fl file is " + mFlFilePath);
ParcelFileDescriptor flFd = null;
@@ -154,124 +160,4 @@
mMediaPlayer.release();
}
}
-
- private boolean convertDmToFl(int res, String flFilePath) throws Exception {
- AssetFileDescriptor afd = getContext().getResources().openRawResourceFd(res);
- FileInputStream inputStream = afd.createInputStream();
- int inputLength = (int)afd.getLength();
- byte[] fileData = new byte[inputLength];
- int readSize = inputStream.read(fileData, 0, inputLength);
- assertEquals("can not pull in all data", readSize, inputLength);
- inputStream.close();
- afd.close();
-
- FileOutputStream flStream = new FileOutputStream(new File(flFilePath));
-
- DrmManagerClient drmClient = null;
- try {
- drmClient = new DrmManagerClient(mContext);
- } catch (IllegalArgumentException e) {
- Log.w(TAG, "DrmManagerClient instance could not be created, context is Illegal.");
- return false;
- } catch (IllegalStateException e) {
- Log.w(TAG, "DrmManagerClient didn't initialize properly.");
- return false;
- }
-
- if (drmClient == null) {
- Log.w(TAG, "Failed to create DrmManagerClient.");
- return false;
- }
-
- int convertSessionId = -1;
- try {
- convertSessionId = drmClient.openConvertSession(MIMETYPE_DRM_MESSAGE);
- } catch (IllegalArgumentException e) {
- Log.w(TAG, "Conversion of Mimetype: " + MIMETYPE_DRM_MESSAGE
- + " is not supported.", e);
- return false;
- } catch (IllegalStateException e) {
- Log.w(TAG, "Could not access Open DrmFramework.", e);
- return false;
- }
-
- if (convertSessionId < 0) {
- Log.w(TAG, "Failed to open session.");
- return false;
- }
-
- DrmConvertedStatus convertedStatus = null;
- try {
- convertedStatus = drmClient.convertData(convertSessionId, fileData);
- } catch (IllegalArgumentException e) {
- Log.w(TAG, "Buffer with data to convert is illegal. Convertsession: "
- + convertSessionId, e);
- return false;
- } catch (IllegalStateException e) {
- Log.w(TAG, "Could not convert data. Convertsession: " + convertSessionId, e);
- return false;
- }
-
- if (convertedStatus == null ||
- convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK ||
- convertedStatus.convertedData == null) {
- Log.w(TAG, "Error in converting data. Convertsession: " + convertSessionId);
- try {
- drmClient.closeConvertSession(convertSessionId);
- } catch (IllegalStateException e) {
- Log.w(TAG, "Could not close session. Convertsession: " +
- convertSessionId, e);
- }
- return false;
- }
-
- flStream.write(convertedStatus.convertedData, 0, convertedStatus.convertedData.length);
- flStream.close();
-
- try {
- convertedStatus = drmClient.closeConvertSession(convertSessionId);
- } catch (IllegalStateException e) {
- Log.w(TAG, "Could not close convertsession. Convertsession: " +
- convertSessionId, e);
- return false;
- }
-
- if (convertedStatus == null ||
- convertedStatus.statusCode != DrmConvertedStatus.STATUS_OK ||
- convertedStatus.convertedData == null) {
- Log.w(TAG, "Error in closing session. Convertsession: " + convertSessionId);
- return false;
- }
-
- RandomAccessFile flRandomAccessFile = null;
- try {
- flRandomAccessFile = new RandomAccessFile(flFilePath, "rw");
- flRandomAccessFile.seek(convertedStatus.offset);
- flRandomAccessFile.write(convertedStatus.convertedData);
- } catch (FileNotFoundException e) {
- Log.w(TAG, "File: " + flFilePath + " could not be found.", e);
- return false;
- } catch (IOException e) {
- Log.w(TAG, "Could not access File: " + flFilePath + " .", e);
- return false;
- } catch (IllegalArgumentException e) {
- Log.w(TAG, "Could not open file in mode: rw", e);
- return false;
- } catch (SecurityException e) {
- Log.w(TAG, "Access to File: " + flFilePath +
- " was denied denied by SecurityManager.", e);
- return false;
- } finally {
- if (flRandomAccessFile != null) {
- try {
- flRandomAccessFile.close();
- } catch (IOException e) {
- Log.w(TAG, "Failed to close File:" + flFilePath + ".", e);
- return false;
- }
- }
- }
-
- return true;
- }
}
diff --git a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
index c63cb66..e29cbdb 100644
--- a/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
+++ b/tests/tests/security/src/android/security/cts/PackageSignatureTest.java
@@ -94,9 +94,6 @@
// APK for an activity that collects information printed in the CTS report header
"android.tests.devicesetup",
- // APK for the Android core tests runner used only during CTS
- "android.core.tests.runner",
-
// Wifi test utility used by Tradefed...
"com.android.tradefed.utils.wifi",
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherApiTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherApiTest.java
index 177ce5e..b345b6f 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherApiTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerLauncherApiTest.java
@@ -252,7 +252,7 @@
"Launcher_manifest_2",
0,
list()))
- .haveIds("ms21", "ms22", "s1", "s5")
+ .haveIds("ms21", "ms22", "s5")
.areAllNotWithKeyFieldsOnly();
// With ids
diff --git a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerNegativeTest.java b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerNegativeTest.java
index c711518..d81bbfd 100644
--- a/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerNegativeTest.java
+++ b/tests/tests/shortcutmanager/src/android/content/pm/cts/shortcutmanager/ShortcutManagerNegativeTest.java
@@ -22,6 +22,7 @@
import android.content.pm.ShortcutManager;
import android.test.MoreAsserts;
import android.test.suitebuilder.annotation.SmallTest;
+import android.test.suitebuilder.annotation.Suppress;
import android.util.Log;
import java.io.BufferedReader;
@@ -137,6 +138,7 @@
/**
* Make sure cmd shortcut can't be called.
*/
+ @Suppress // calling "cmd shortcut" from this UID seems to hang now.
public void testCommand() throws Exception {
runWithCaller(mPackageContext1, () -> {
assertTrue(getManager().setDynamicShortcuts(list(
diff --git a/tests/tests/text/src/android/text/cts/StaticLayoutTest.java b/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
index 40acb50..f1e883c 100644
--- a/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
+++ b/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
@@ -1291,7 +1291,8 @@
final SpannableString spannable = new SpannableString(text);
spannable.setSpan(new Object(), 0, text.length(), SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
final Layout layout = StaticLayout.Builder.obtain(spannable, 0, spannable.length(),
- mDefaultPaint, Integer.MAX_VALUE - 1).setMaxLines(2).build();
+ mDefaultPaint, Integer.MAX_VALUE - 1).setMaxLines(2)
+ .setEllipsize(TruncateAt.END).build();
layout.getPrimaryHorizontal(layout.getText().length());
}
@@ -1299,7 +1300,8 @@
public void testGetPrimary_shouldFail_whenOffsetIsOutOfBounds_withString() {
final String text = "1\n2\n3";
final Layout layout = StaticLayout.Builder.obtain(text, 0, text.length(),
- mDefaultPaint, Integer.MAX_VALUE - 1).setMaxLines(2).build();
+ mDefaultPaint, Integer.MAX_VALUE - 1).setMaxLines(2)
+ .setEllipsize(TruncateAt.END).build();
layout.getPrimaryHorizontal(layout.getText().length());
}
diff --git a/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java b/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java
index 8317775..e06e6fb 100644
--- a/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java
+++ b/tests/tests/transition/src/android/transition/cts/ActivityTransitionTest.java
@@ -34,6 +34,7 @@
import android.os.Bundle;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
+import android.transition.Fade;
import android.transition.Transition.TransitionListener;
import android.view.View;
@@ -222,6 +223,42 @@
TargetActivity.sLastCreated = null;
}
+ // When an exit transition takes longer than it takes the activity to cover it (and onStop
+ // is called), the exiting views should become visible.
+ @Test
+ public void earlyExitStop() throws Throwable {
+ enterScene(R.layout.scene1);
+ final View hello = mActivity.findViewById(R.id.hello);
+ final View red = mActivity.findViewById(R.id.redSquare);
+ final View green = mActivity.findViewById(R.id.greenSquare);
+ mInstrumentation.runOnMainSync(() -> {
+ Fade fade = new Fade();
+ fade.setDuration(10000);
+ fade.addListener(mExitListener);
+ mActivity.getWindow().setExitTransition(fade);
+ Bundle options = ActivityOptions.makeSceneTransitionAnimation(mActivity).toBundle();
+ Intent intent = new Intent(mActivity, TargetActivity.class);
+ intent.putExtra(TargetActivity.EXTRA_LAYOUT_ID, R.layout.scene4);
+ mActivity.startActivity(intent, options);
+ });
+
+ TargetActivity targetActivity = waitForTargetActivity();
+ verify(targetActivity.enterListener, within(3000)).onTransitionEnd(any());
+ verify(mExitListener, within(3000)).onTransitionEnd(any());
+
+ mInstrumentation.runOnMainSync(() -> {
+ // Verify that the exited views have an alpha of 1 and are visible
+ assertEquals(1.0f, hello.getAlpha(), 0.01f);
+ assertEquals(1.0f, red.getAlpha(), 0.01f);
+ assertEquals(1.0f, green.getAlpha(), 0.01f);
+
+ assertEquals(View.VISIBLE, hello.getVisibility());
+ assertEquals(View.VISIBLE, red.getVisibility());
+ assertEquals(View.VISIBLE, green.getVisibility());
+ targetActivity.finish();
+ });
+ }
+
private TargetActivity waitForTargetActivity() {
PollingCheck.waitFor(() -> TargetActivity.sLastCreated != null);
// Just make sure that we're not in the middle of running on the UI thread.
diff --git a/tests/tests/uirendering/res/drawable-nodpi/golden_headless_robot.png b/tests/tests/uirendering/res/drawable-nodpi/golden_headless_robot.png
deleted file mode 100644
index 0bf0272..0000000
--- a/tests/tests/uirendering/res/drawable-nodpi/golden_headless_robot.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/golden_robot.png b/tests/tests/uirendering/res/drawable-nodpi/golden_robot.png
deleted file mode 100644
index ef3631a..0000000
--- a/tests/tests/uirendering/res/drawable-nodpi/golden_robot.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/uirendering/res/drawable-nodpi/robot.png b/tests/tests/uirendering/res/drawable-nodpi/robot.png
deleted file mode 100644
index 72a065c..0000000
--- a/tests/tests/uirendering/res/drawable-nodpi/robot.png
+++ /dev/null
Binary files differ
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java
deleted file mode 100644
index 4d6c04d..0000000
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/HardwareBitmapTests.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.uirendering.cts.testclasses;
-
-import android.graphics.BitmapRegionDecoder;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.uirendering.cts.R;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.support.test.filters.MediumTest;
-import android.uirendering.cts.bitmapcomparers.ExactComparer;
-import android.uirendering.cts.bitmapverifiers.GoldenImageVerifier;
-import android.uirendering.cts.testinfrastructure.ActivityTestBase;
-
-import org.junit.Test;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-@MediumTest
-public class HardwareBitmapTests extends ActivityTestBase {
-
- @Test
- public void testDecodeResource() {
- createTest().addCanvasClient((canvas, width, height) -> {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inPreferredConfig = Bitmap.Config.HARDWARE;
- Bitmap hardwareBitmap = BitmapFactory.decodeResource(
- getActivity().getResources(), R.drawable.robot, options);
- canvas.drawBitmap(hardwareBitmap, 0, 0, new Paint());
- }, true).runWithVerifier(new GoldenImageVerifier(getActivity(),
- R.drawable.golden_robot, new ExactComparer()));
- }
-
- @Test
- public void testBitmapRegionDecode() throws IOException {
- InputStream inputStream = getActivity().getResources().openRawResource(R.drawable.robot);
- BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(inputStream, false);
- createTest().addCanvasClient((canvas, width, height) -> {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inPreferredConfig = Bitmap.Config.HARDWARE;
- Bitmap hardwareBitmap = decoder.decodeRegion(new Rect(10, 15, 34, 39), options);
- canvas.drawBitmap(hardwareBitmap, 0, 0, new Paint());
- }, true).runWithVerifier(new GoldenImageVerifier(getActivity(),
- R.drawable.golden_headless_robot, new ExactComparer()));
- }
-
-}
diff --git a/tests/tests/view/res/layout/hover_layout.xml b/tests/tests/view/res/layout/hover_layout.xml
index 07e4a95..08bbede 100644
--- a/tests/tests/view/res/layout/hover_layout.xml
+++ b/tests/tests/view/res/layout/hover_layout.xml
@@ -22,10 +22,9 @@
<LinearLayout
android:id="@+id/outer"
- android:orientation="horizontal"
+ android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="20dp"
android:gravity="center"
android:background="#eee">
@@ -33,21 +32,21 @@
android:id="@+id/middle1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="40dp"
+ android:layout_margin="@dimen/hover_target_margin"
android:background="#ddd">
<LinearLayout
android:id="@+id/inner11"
- android:layout_width="20dp"
- android:layout_height="20dp"
- android:layout_margin="20dp"
+ android:layout_width="@dimen/hover_target_size"
+ android:layout_height="@dimen/hover_target_size"
+ android:layout_margin="@dimen/hover_target_margin"
android:background="#bbb"/>
<TextView
android:id="@+id/inner12"
android:layout_width="wrap_content"
- android:layout_height="20dp"
- android:layout_margin="20dp"
+ android:layout_height="@dimen/hover_target_size"
+ android:layout_margin="@dimen/hover_target_margin"
android:text="Text"/>
</LinearLayout>
@@ -56,30 +55,30 @@
android:id="@+id/middle2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_margin="40dp"
+ android:layout_margin="@dimen/hover_target_margin"
android:background="#ddd">
<LinearLayout
android:id="@+id/inner21"
- android:layout_width="20dp"
- android:layout_height="20dp"
- android:layout_margin="20dp"
+ android:layout_width="@dimen/hover_target_size"
+ android:layout_height="@dimen/hover_target_size"
+ android:layout_margin="@dimen/hover_target_margin"
android:background="#bbb"/>
<TextView
android:id="@+id/inner22"
android:layout_width="wrap_content"
- android:layout_height="20dp"
- android:layout_margin="20dp"
+ android:layout_height="@dimen/hover_target_size"
+ android:layout_margin="@dimen/hover_target_margin"
android:text="Text"/>
</LinearLayout>
<RelativeLayout
android:id="@+id/overlapping"
- android:layout_width="100dp"
- android:layout_height="20dp"
- android:layout_margin="20dp"
+ android:layout_width="@dimen/hover_target_size_double"
+ android:layout_height="@dimen/hover_target_size"
+ android:layout_margin="@dimen/hover_target_margin"
android:background="#ddd">
<View
@@ -99,12 +98,12 @@
<View
android:id="@+id/layer4_left"
- android:layout_width="50dp"
+ android:layout_width="@dimen/hover_target_size"
android:layout_height="match_parent"/>
<View
android:id="@+id/layer4_right"
- android:layout_width="50dp"
+ android:layout_width="@dimen/hover_target_size"
android:layout_height="match_parent"
android:layout_toRightOf="@+id/layer4_left" />
diff --git a/tests/tests/view/res/layout/view_padding.xml b/tests/tests/view/res/layout/view_padding.xml
new file mode 100644
index 0000000..e3b0deb
--- /dev/null
+++ b/tests/tests/view/res/layout/view_padding.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view1"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:padding="@dimen/insetAll"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view2"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:paddingLeft="@dimen/insetLeft"
+ android:paddingTop="@dimen/insetTop"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view3"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:paddingRight="@dimen/insetRight"
+ android:paddingBottom="@dimen/insetBottom"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view4"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:paddingLeft="@dimen/insetLeft"
+ android:paddingTop="@dimen/insetTop"
+ android:paddingRight="@dimen/insetRight"
+ android:paddingBottom="@dimen/insetBottom"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view5"/>
+ </LinearLayout>
+
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:paddingHorizontal="@dimen/insetHorizontal"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view6"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:paddingVertical="@dimen/insetVertical"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view7"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:paddingHorizontal="@dimen/insetHorizontal"
+ android:paddingVertical="@dimen/insetVertical"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view8"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:paddingHorizontal="@dimen/insetHorizontal"
+ android:paddingVertical="@dimen/insetVertical"
+ android:paddingLeft="0dp"
+ android:paddingTop="0dp"
+ android:paddingRight="0dp"
+ android:paddingBottom="0dp"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view9"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:padding="@dimen/insetAll"
+ android:paddingLeft="0dp"
+ android:paddingTop="0dp"
+ android:paddingRight="0dp"
+ android:paddingBottom="0dp"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view10"/>
+ </LinearLayout>
+
+</LinearLayout>
+
diff --git a/tests/tests/view/res/layout/viewgroup_margin_layout_verticalhorizontal.xml b/tests/tests/view/res/layout/viewgroup_margin_layout_verticalhorizontal.xml
new file mode 100644
index 0000000..a1c4051
--- /dev/null
+++ b/tests/tests/view/res/layout/viewgroup_margin_layout_verticalhorizontal.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/view1"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginHorizontal="10dp"
+ android:id="@+id/view2"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginVertical="10dp"
+ android:id="@+id/view3"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginHorizontal="10dp"
+ android:layout_marginVertical="10dp"
+ android:id="@+id/view4"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginHorizontal="10dp"
+ android:layout_marginLeft="5dp"
+ android:layout_marginRight="2dp"
+ android:layout_marginVertical="10dp"
+ android:layout_marginTop="5dp"
+ android:layout_marginBottom="2dp"
+ android:id="@+id/view5"/>
+ </LinearLayout>
+
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="100dp">
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginHorizontal="10dp"
+ android:layout_marginStart="5dp"
+ android:layout_marginEnd="2dp"
+ android:layout_marginVertical="10dp"
+ android:id="@+id/view6"/>
+ </LinearLayout>
+
+</LinearLayout>
+
diff --git a/tests/tests/view/res/values/dimens.xml b/tests/tests/view/res/values/dimens.xml
index 16e5084..59369a7 100644
--- a/tests/tests/view/res/values/dimens.xml
+++ b/tests/tests/view/res/values/dimens.xml
@@ -20,4 +20,14 @@
<dimen name="reset_state_value">50dp</dimen>
<!-- this value is equal to the value in changing_state_list_animator. It is NOT referenced in the XML on purpose-->
<dimen name="changing_state_list_anim_target_x_value">100dp</dimen>
+ <dimen name="insetLeft">5dp</dimen>
+ <dimen name="insetTop">6dp</dimen>
+ <dimen name="insetRight">7dp</dimen>
+ <dimen name="insetBottom">8dp</dimen>
+ <dimen name="insetAll">9dp</dimen>
+ <dimen name="insetHorizontal">10dp</dimen>
+ <dimen name="insetVertical">11dp</dimen>
+ <dimen name="hover_target_margin">4dp</dimen>
+ <dimen name="hover_target_size">8dp</dimen>
+ <dimen name="hover_target_size_double">16dp</dimen>
</resources>
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
index af34cdc..34a6020 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
@@ -25,6 +25,7 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
@@ -216,4 +217,44 @@
assertEquals(true, mMarginLayoutParams.isMarginRelative());
}
+
+ @Test
+ public void testVerticalHorizontalMargins() {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+
+ LinearLayout viewGroup = (LinearLayout)
+ inflater.inflate(R.layout.viewgroup_margin_layout_verticalhorizontal, null);
+ int measureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY);
+ viewGroup.measure(measureSpec, measureSpec);
+ viewGroup.layout(0, 0, 1000, 1000);
+
+ View view1 = viewGroup.findViewById(R.id.view1);
+ View view2 = viewGroup.findViewById(R.id.view2);
+ View view3 = viewGroup.findViewById(R.id.view3);
+ View view4 = viewGroup.findViewById(R.id.view4);
+ View view5 = viewGroup.findViewById(R.id.view5);
+ View view6 = viewGroup.findViewById(R.id.view6);
+
+ int defaultWidth = view1.getWidth();
+ int defaultHeight = view1.getHeight();
+ int marginPixels = (int) (mContext.getResources().getDisplayMetrics().density * 10 + .5f);
+
+ assertEquals("Width value", defaultWidth, view1.getWidth());
+ assertEquals("Height value", defaultHeight, view1.getHeight());
+
+ assertEquals("Width value", defaultWidth - 2 * marginPixels, view2.getWidth());
+ assertEquals("Height value", defaultHeight, view2.getHeight());
+
+ assertEquals("Width value", defaultWidth, view3.getWidth());
+ assertEquals("Height value", defaultHeight - 2 * marginPixels, view3.getHeight());
+
+ assertEquals("Width value", defaultWidth - 2 * marginPixels, view4.getWidth());
+ assertEquals("Height value", defaultHeight - 2 * marginPixels, view4.getHeight());
+
+ assertEquals("Width value", defaultWidth - 2 * marginPixels, view5.getWidth());
+ assertEquals("Height value", defaultHeight - 2 * marginPixels, view5.getHeight());
+
+ assertEquals("Width value", defaultWidth - 2 * marginPixels, view6.getWidth());
+ assertEquals("Height value", defaultHeight - 2 * marginPixels, view6.getHeight());
+ }
}
diff --git a/tests/tests/view/src/android/view/cts/ViewPaddingTest.java b/tests/tests/view/src/android/view/cts/ViewPaddingTest.java
new file mode 100644
index 0000000..b146f9d
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ViewPaddingTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.cts;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ViewPaddingTest {
+ private Context mContext;
+
+ @Before
+ public void setup() {
+ mContext = InstrumentationRegistry.getTargetContext();
+ }
+
+ @Test
+ public void testPadding() {
+ LayoutInflater inflater = LayoutInflater.from(mContext);
+
+ LinearLayout viewGroup = (LinearLayout)
+ inflater.inflate(R.layout.view_padding, null);
+ int measureSpec = View.MeasureSpec.makeMeasureSpec(1000, View.MeasureSpec.EXACTLY);
+ viewGroup.measure(measureSpec, measureSpec);
+ viewGroup.layout(0, 0, 1000, 1000);
+
+ View view1 = viewGroup.findViewById(R.id.view1);
+ View view2 = viewGroup.findViewById(R.id.view2);
+ View view3 = viewGroup.findViewById(R.id.view3);
+ View view4 = viewGroup.findViewById(R.id.view4);
+ View view5 = viewGroup.findViewById(R.id.view5);
+ View view6 = viewGroup.findViewById(R.id.view6);
+ View view7 = viewGroup.findViewById(R.id.view7);
+ View view8 = viewGroup.findViewById(R.id.view8);
+ View view9 = viewGroup.findViewById(R.id.view9);
+ View view10 = viewGroup.findViewById(R.id.view10);
+
+ Rect defaultBounds = new Rect(view1.getLeft(), view1.getTop(), view1.getRight(),
+ view1.getBottom());
+ int insetLeft = mContext.getResources().getDimensionPixelSize(R.dimen.insetLeft);
+ int insetRight = mContext.getResources().getDimensionPixelSize(R.dimen.insetRight);
+ int insetTop = mContext.getResources().getDimensionPixelSize(R.dimen.insetTop);
+ int insetBottom = mContext.getResources().getDimensionPixelSize(R.dimen.insetBottom);
+ int insetAll = mContext.getResources().getDimensionPixelSize(R.dimen.insetAll);
+ int insetHorizontal =
+ mContext.getResources().getDimensionPixelSize(R.dimen.insetHorizontal);
+ int insetVertical = mContext.getResources().getDimensionPixelSize(R.dimen.insetVertical);
+
+ checkBounds(view2, defaultBounds, insetAll, insetAll, insetAll, insetAll);
+ checkBounds(view3, defaultBounds, insetLeft, insetTop, 0, 0);
+ checkBounds(view4, defaultBounds, 0, 0, insetRight, insetBottom);
+ checkBounds(view5, defaultBounds, insetLeft, insetTop, insetRight, insetBottom);
+ checkBounds(view6, defaultBounds, insetHorizontal, 0, insetHorizontal, 0);
+ checkBounds(view7, defaultBounds, 0, insetVertical, 0, insetVertical);
+ checkBounds(view8, defaultBounds, insetHorizontal, insetVertical, insetHorizontal,
+ insetVertical);
+ checkBounds(view9, defaultBounds, insetHorizontal, insetVertical, insetHorizontal,
+ insetVertical);
+ checkBounds(view10, defaultBounds, insetAll, insetAll, insetAll, insetAll);
+ }
+
+ private void checkBounds(View view, Rect defaultBounds,
+ int insetLeft, int insetTop, int insetRight, int insetBottom) {
+ assertEquals("Left", defaultBounds.left + insetLeft, view.getLeft());
+ assertEquals("Top", defaultBounds.top + insetTop, view.getTop());
+ assertEquals("Right", defaultBounds.right - insetRight, view.getRight());
+ assertEquals("Bottom", defaultBounds.bottom - insetBottom, view.getBottom());
+ }
+}
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 9151783..a011b97 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -2574,6 +2574,35 @@
assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
}
+ @UiThreadTest
+ public void testGetWebViewClient() throws Exception {
+ // getWebViewClient should return a default WebViewClient if it hasn't been set yet
+ WebView webView = new WebView(getActivity());
+ WebViewClient client = webView.getWebViewClient();
+ assertNotNull(client);
+ assertTrue(client instanceof WebViewClient);
+
+ // getWebViewClient should return the client after it has been set
+ WebViewClient client2 = new WebViewClient();
+ assertNotSame(client, client2);
+ webView.setWebViewClient(client2);
+ assertSame(client2, webView.getWebViewClient());
+ }
+
+ @UiThreadTest
+ public void testGetWebChromeClient() throws Exception {
+ // getWebChromeClient should return null if the client hasn't been set yet
+ WebView webView = new WebView(getActivity());
+ WebChromeClient client = webView.getWebChromeClient();
+ assertNull(client);
+
+ // getWebChromeClient should return the client after it has been set
+ WebChromeClient client2 = new WebChromeClient();
+ assertNotSame(client, client2);
+ webView.setWebChromeClient(client2);
+ assertSame(client2, webView.getWebChromeClient());
+ }
+
private void savePrintedPage(final PrintDocumentAdapter adapter,
final ParcelFileDescriptor descriptor, final FutureTask<Boolean> result) {
adapter.onWrite(new PageRange[] {PageRange.ALL_PAGES}, descriptor,
diff --git a/tests/tests/widget/res/layout/edittext_layout.xml b/tests/tests/widget/res/layout/edittext_layout.xml
index 0de7208..64a41e5 100644
--- a/tests/tests/widget/res/layout/edittext_layout.xml
+++ b/tests/tests/widget/res/layout/edittext_layout.xml
@@ -46,5 +46,14 @@
android:maxLines="3"
android:textColor="#FF0000"
android:text="@string/edit_text" />
+
+ <EditText
+ android:id="@+id/edittext_autosize"
+ android:layout_width="300dp"
+ android:layout_height="400dp"
+ android:text="@string/long_text"
+ android:autoSizeText="xy"
+ android:textSize="50dp"
+ android:autoSizeStepGranularity="2dp" />
</LinearLayout>
</ScrollView>
diff --git a/tests/tests/widget/src/android/widget/cts/EditTextTest.java b/tests/tests/widget/src/android/widget/cts/EditTextTest.java
index ac41358..5dfefb3 100644
--- a/tests/tests/widget/src/android/widget/cts/EditTextTest.java
+++ b/tests/tests/widget/src/android/widget/cts/EditTextTest.java
@@ -32,6 +32,8 @@
import android.text.method.ArrowKeyMovementMethod;
import android.text.method.MovementMethod;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.TypedValue;
import android.util.Xml;
import android.widget.EditText;
import android.widget.TextView.BufferType;
@@ -225,6 +227,18 @@
}
@Test
+ public void testAutoSizeNotSupported() {
+ DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
+ EditText autoSizeEditText = (EditText) mActivity.findViewById(R.id.edittext_autosize);
+
+ // If auto-size would work then the text size would be less then 50dp (the value set in the
+ // layout file).
+ final float sizeSetInPixels = TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP, 50f, metrics);
+ assertEquals(sizeSetInPixels, autoSizeEditText.getTextSize(), 0f);
+ }
+
+ @Test
public void testGetDefaultMovementMethod() {
MockEditText mockEditText = new MockEditText(mActivity, mAttributeSet);
MovementMethod method1 = mockEditText.getDefaultMovementMethod();
diff --git a/tools/cts-java-scanner-doclet/Android.mk b/tools/cts-java-scanner-doclet/Android.mk
deleted file mode 100644
index d647537..0000000
--- a/tools/cts-java-scanner-doclet/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := cts-java-scanner-doclet
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
-LOCAL_JAVA_LIBRARIES := junit
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java b/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java
deleted file mode 100644
index 9982777..0000000
--- a/tools/cts-java-scanner-doclet/src/com/android/cts/javascannerdoclet/CtsJavaScannerDoclet.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.javascannerdoclet;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import com.sun.javadoc.AnnotationDesc;
-import com.sun.javadoc.AnnotationTypeDoc;
-import com.sun.javadoc.AnnotationValue;
-import com.sun.javadoc.ClassDoc;
-import com.sun.javadoc.Doclet;
-import com.sun.javadoc.MethodDoc;
-import com.sun.javadoc.RootDoc;
-import com.sun.javadoc.AnnotationDesc.ElementValuePair;
-import com.sun.javadoc.AnnotationTypeElementDoc;
-
-/**
- * Doclet that outputs in the following format:
- *
- * suite:android.holo.cts
- * case:HoloTest
- * test:testHolo
- * test:testHoloDialog
- */
-public class CtsJavaScannerDoclet extends Doclet {
-
- private static final String JUNIT4_TEST_ANNOTATION = "org.junit.Test";
-
- static final String JUNIT_TEST_CASE_CLASS_NAME = "junit.framework.testcase";
- private static final String SUPPRESS_ANNOTATION =
- "android.test.suitebuilder.annotation.Suppress";
-
- public static boolean start(RootDoc root) {
- ClassDoc[] classes = root.classes();
- if (classes == null) {
- return false;
- }
-
- PrintWriter writer = new PrintWriter(System.out);
-
- for (ClassDoc clazz : classes) {
- if (clazz.isAbstract()) {
- continue;
- }
-
- final boolean isJUnit3 = isJUnit3TestCase(clazz);
- if (!isJUnit3 && !isJUnit4TestClass(clazz)) {
- continue;
- }
-
- writer.append("suite:").println(clazz.containingPackage().name());
- writer.append("case:").println(clazz.name());
- for (; clazz != null; clazz = clazz.superclass()) {
- for (MethodDoc method : clazz.methods()) {
- int timeout = -1;
- if (isJUnit3) {
- if (!method.name().startsWith("test")) {
- continue;
- }
-
- boolean suppressed = false;
- AnnotationDesc[] annotations = method.annotations();
- for (AnnotationDesc annot : annotations) {
- String atype = annot.annotationType().toString();
- if (atype.equals(SUPPRESS_ANNOTATION)) {
- suppressed = true;
- }
- }
- if (suppressed) {
- continue;
- }
- } else {
- /* JUnit4 */
- boolean isTest = false;
-
- for (AnnotationDesc annot : method.annotations()) {
- if (annot.annotationType().toString().equals(JUNIT4_TEST_ANNOTATION)) {
- isTest = true;
-
- for (ElementValuePair pair : annot.elementValues()) {
- if (pair.element().name().equals("timeout")) {
- /* JUnit4 timeouts are in milliseconds. */
- timeout = (int) (((Long) pair.value().value()) / 60000L);
- }
- }
- }
- }
-
- if (!isTest) {
- continue;
- }
- }
-
- writer.append("test:");
- if (timeout >= 0) {
- writer.append(method.name()).println(":" + timeout);
- } else {
- writer.println(method.name());
- }
- }
- }
- }
-
- writer.close();
- return true;
- }
-
- private static boolean isJUnit3TestCase(ClassDoc clazz) {
- while((clazz = clazz.superclass()) != null) {
- if (JUNIT_TEST_CASE_CLASS_NAME.equals(clazz.qualifiedName().toLowerCase())) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean isJUnit4TestClass(ClassDoc clazz) {
- for (MethodDoc method : clazz.methods()) {
- for (AnnotationDesc annot : method.annotations()) {
- if (annot.annotationType().toString().equals(JUNIT4_TEST_ANNOTATION)) {
- return true;
- }
- }
- }
- return false;
- }
-}
diff --git a/tools/cts-java-scanner/Android.mk b/tools/cts-java-scanner/Android.mk
deleted file mode 100644
index 644f1c0..0000000
--- a/tools/cts-java-scanner/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# the hat script
-# ============================================================
-include $(CLEAR_VARS)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE := cts-java-scanner
-LOCAL_SRC_FILES := etc/$(LOCAL_MODULE)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(HOST_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
-include $(BUILD_PREBUILT)
-
-# the other stuff
-# ============================================================
-subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
- src \
- ))
-
-include $(subdirs)
diff --git a/tools/cts-java-scanner/etc/cts-java-scanner b/tools/cts-java-scanner/etc/cts-java-scanner
deleted file mode 100644
index 378eee8..0000000
--- a/tools/cts-java-scanner/etc/cts-java-scanner
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2011, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-libdir=`dirname $progdir`/framework
-
-javaOpts=""
-while expr "x$1" : 'x-J' >/dev/null; do
- opt=`expr "$1" : '-J\(.*\)'`
- javaOpts="${javaOpts} -${opt}"
- shift
-done
-
-exec java $javaOpts -jar $libdir/cts-java-scanner.jar "$@"
diff --git a/tools/cts-java-scanner/src/Android.mk b/tools/cts-java-scanner/src/Android.mk
deleted file mode 100644
index ec42bcf..0000000
--- a/tools/cts-java-scanner/src/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-
-# cts-java-scanner java library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-LOCAL_MODULE := cts-java-scanner
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/cts-java-scanner/src/MANIFEST.mf b/tools/cts-java-scanner/src/MANIFEST.mf
deleted file mode 100644
index 642f226..0000000
--- a/tools/cts-java-scanner/src/MANIFEST.mf
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: com.android.cts.javascanner.CtsJavaScanner
diff --git a/tools/cts-java-scanner/src/com/android/cts/javascanner/CtsJavaScanner.java b/tools/cts-java-scanner/src/com/android/cts/javascanner/CtsJavaScanner.java
deleted file mode 100644
index fc774e9..0000000
--- a/tools/cts-java-scanner/src/com/android/cts/javascanner/CtsJavaScanner.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.javascanner;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Class that searches a source directory for native gTests and outputs a
- * list of test classes and methods.
- */
-public class CtsJavaScanner {
-
- private static void usage(String[] args) {
- System.err.println("Arguments: " + Arrays.asList(args));
- System.err.println("Usage: cts-java-scanner -s SOURCE_DIR -d DOCLET_PATH");
- System.exit(1);
- }
-
- public static void main(String[] args) throws Exception {
- List<File> sourceDirs = new ArrayList<File>();
- File docletPath = null;
-
- for (int i = 0; i < args.length; i++) {
- if ("-s".equals(args[i])) {
- sourceDirs.add(new File(getArg(args, ++i, "Missing value for source directory")));
- } else if ("-d".equals(args[i])) {
- docletPath = new File(getArg(args, ++i, "Missing value for docletPath"));
- } else {
- System.err.println("Unsupported flag: " + args[i]);
- usage(args);
- }
- }
-
- if (sourceDirs.isEmpty()) {
- System.err.println("Source directory is required");
- usage(args);
- }
-
- if (docletPath == null) {
- System.err.println("Doclet path is required");
- usage(args);
- }
-
- DocletRunner runner = new DocletRunner(sourceDirs, docletPath);
- System.exit(runner.runJavaDoc());
- }
-
- private static String getArg(String[] args, int index, String message) {
- if (index < args.length) {
- return args[index];
- } else {
- System.err.println(message);
- usage(args);
- return null;
- }
- }
-}
diff --git a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
deleted file mode 100644
index fb6691d..0000000
--- a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.javascanner;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileFilter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-
-class DocletRunner {
-
- private final List<File> mSourceDirs;
- private final File mDocletPath;
-
- DocletRunner(List<File> sourceDirs, File docletPath) {
- mSourceDirs = sourceDirs;
- mDocletPath = docletPath;
- }
-
- int runJavaDoc() throws IOException, InterruptedException {
- List<String> args = new ArrayList<String>();
- args.add("javadoc");
- args.add("-doclet");
- args.add("com.android.cts.javascannerdoclet.CtsJavaScannerDoclet");
- args.add("-docletpath");
- args.add(mDocletPath.toString());
- args.add("-sourcepath");
- args.add(getSourcePath(mSourceDirs));
- args.add("-classpath");
- args.add(getClassPath());
- for (File sourceDir : mSourceDirs) {
- args.addAll(getSourceFiles(sourceDir));
- }
-
-
- // NOTE: We redirect the error stream to make sure the child process
- // isn't blocked due to a full pipe. (The javadoc tool writes source errors
- // to stderr.)
- Process process = new ProcessBuilder(args).redirectErrorStream(true).start();
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(process.getInputStream()));
- try {
- String line = null;
- while ((line = reader.readLine()) != null) {
- System.out.println(line);
- }
- } finally {
- if (reader != null) {
- reader.close();
- }
- }
-
- return process.waitFor();
- }
-
- private String getSourcePath(List<File> sourceDirs) {
- List<String> sourcePath = new ArrayList<String>();
- sourcePath.add("./frameworks/base/core/java");
- sourcePath.add("./frameworks/base/test-runner/src");
- sourcePath.add("./external/junit/src");
- sourcePath.add("./development/tools/hosttestlib/src");
- sourcePath.add("./libcore/dalvik/src/main/java");
- sourcePath.add("./cts/tests/src");
- sourcePath.add("./cts/libs/commonutil/src");
- sourcePath.add("./cts/libs/deviceutil/src");
- for (File sourceDir : sourceDirs) {
- sourcePath.add(sourceDir.toString());
- }
- return join(sourcePath, ":");
- }
-
- private String getClassPath() {
- List<String> classPath = new ArrayList<String>();
- classPath.add("./prebuilts/misc/common/tradefed/tradefed-prebuilt.jar");
- classPath.add("./prebuilts/misc/common/ub-uiautomator/ub-uiautomator.jar");
- classPath.add("./prebuilts/misc/common/ub-janktesthelper/ub-janktesthelper.jar");
- return join(classPath, ":");
- }
-
- private List<String> getSourceFiles(File sourceDir) {
- List<String> sourceFiles = new ArrayList<String>();
-
- File[] files = sourceDir.listFiles(new FileFilter() {
- @Override
- public boolean accept(File pathname) {
- return pathname.isDirectory() || pathname.toString().endsWith(".java");
- }
- });
-
- for (File file : files) {
- if (file.isDirectory()) {
- sourceFiles.addAll(getSourceFiles(file));
- } else {
- sourceFiles.add(file.toString());
- }
- }
-
- return sourceFiles;
- }
-
- private String join(List<String> options, String delimiter) {
- StringBuilder builder = new StringBuilder();
- int numOptions = options.size();
- for (int i = 0; i < numOptions; i++) {
- builder.append(options.get(i));
- if (i + 1 < numOptions) {
- builder.append(delimiter);
- }
- }
- return builder.toString();
- }
-}
diff --git a/tools/cts-native-scanner/Android.mk b/tools/cts-native-scanner/Android.mk
deleted file mode 100644
index 203b482..0000000
--- a/tools/cts-native-scanner/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# the hat script
-# ============================================================
-include $(CLEAR_VARS)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE := cts-native-scanner
-LOCAL_SRC_FILES := etc/$(LOCAL_MODULE)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(HOST_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
-include $(BUILD_PREBUILT)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/cts-native-scanner/etc/cts-native-scanner b/tools/cts-native-scanner/etc/cts-native-scanner
deleted file mode 100644
index bf6138f..0000000
--- a/tools/cts-native-scanner/etc/cts-native-scanner
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2011, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-libdir=`dirname $progdir`/framework
-
-javaOpts=""
-while expr "x$1" : 'x-J' >/dev/null; do
- opt=`expr "$1" : '-J\(.*\)'`
- javaOpts="${javaOpts} -${opt}"
- shift
-done
-
-exec java $javaOpts -jar $libdir/cts-native-scanner.jar "$@"
diff --git a/tools/cts-native-scanner/src/Android.mk b/tools/cts-native-scanner/src/Android.mk
deleted file mode 100644
index 9c97b1d..0000000
--- a/tools/cts-native-scanner/src/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-
-# cts-native-scanner java library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-LOCAL_MODULE := cts-native-scanner
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/cts-native-scanner/src/MANIFEST.mf b/tools/cts-native-scanner/src/MANIFEST.mf
deleted file mode 100644
index 85eb991..0000000
--- a/tools/cts-native-scanner/src/MANIFEST.mf
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: com.android.cts.nativescanner.CtsNativeScanner
diff --git a/tools/cts-native-scanner/src/com/android/cts/nativescanner/CtsNativeScanner.java b/tools/cts-native-scanner/src/com/android/cts/nativescanner/CtsNativeScanner.java
deleted file mode 100644
index 2414138..0000000
--- a/tools/cts-native-scanner/src/com/android/cts/nativescanner/CtsNativeScanner.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.nativescanner;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Class that searches a source directory for native gTests and outputs a
- * list of test classes and methods.
- */
-public class CtsNativeScanner {
-
- private static void usage(String[] args) {
- System.err.println("Arguments: " + Arrays.asList(args));
- System.err.println("Usage: cts-native-scanner -t TEST_SUITE");
- System.err.println(" This code reads from stdin the list of tests.");
- System.err.println(" The format expected:");
- System.err.println(" TEST_CASE_NAME.");
- System.err.println(" TEST_NAME");
- System.exit(1);
- }
-
- public static void main(String[] args) throws Exception {
- String testSuite = null;
- for (int i = 0; i < args.length; i++) {
- if ("-t".equals(args[i])) {
- testSuite = getArg(args, ++i, "Missing value for test suite");
- } else {
- System.err.println("Unsupported flag: " + args[i]);
- usage(args);
- }
- }
-
- if (testSuite == null) {
- System.out.println("Test suite is required");
- usage(args);
- }
-
- BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
- TestScanner scanner = new TestScanner(reader, testSuite);
- for (String name : scanner.getTestNames()) {
- System.out.println(name);
- }
- }
-
- private static String getArg(String[] args, int index, String message) {
- if (index < args.length) {
- return args[index];
- } else {
- System.err.println(message);
- usage(args);
- return null;
- }
- }
-}
diff --git a/tools/cts-native-scanner/src/com/android/cts/nativescanner/TestScanner.java b/tools/cts-native-scanner/src/com/android/cts/nativescanner/TestScanner.java
deleted file mode 100644
index 6fcb353..0000000
--- a/tools/cts-native-scanner/src/com/android/cts/nativescanner/TestScanner.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.nativescanner;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Read from the BufferedReader a list of test case names and test cases.
- *
- * The expected format of the incoming test list:
- * TEST_CASE_NAME.
- * TEST_NAME1
- * TEST_NAME2
- *
- * The output:
- * suite:TestSuite
- * case:TEST_CASE_NAME
- * test:TEST_NAME1
- * test:TEST_NAME2
- */
-class TestScanner {
-
- private final String mTestSuite;
-
- private final BufferedReader mReader;
-
- TestScanner(BufferedReader reader, String testSuite) {
- mTestSuite = testSuite;
- mReader = reader;
- }
-
- public List<String> getTestNames() throws IOException {
- List<String> testNames = new ArrayList<String>();
-
- String testCaseName = null;
- String line;
- while ((line = mReader.readLine()) != null) {
- if (line.length() > 0) {
- if (line.charAt(0) == ' ') {
- if (testCaseName != null) {
- testNames.add("test:" + line.trim());
- } else {
- throw new IOException("TEST_CASE_NAME not defined before first test.");
- }
- } else {
- testCaseName = line.trim();
- if (testCaseName.endsWith(".")) {
- testCaseName = testCaseName.substring(0, testCaseName.length()-1);
- }
- testNames.add("suite:" + mTestSuite);
- testNames.add("case:" + testCaseName);
- }
- }
- }
- return testNames;
- }
-}
diff --git a/tools/cts-native-scanner/tests/Android.mk b/tools/cts-native-scanner/tests/Android.mk
deleted file mode 100644
index 562f0b9..0000000
--- a/tools/cts-native-scanner/tests/Android.mk
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Only compile source java files in this lib
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MODULE := cts-native-scanner-tests
-LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := tradefed cts-native-scanner
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-
diff --git a/tools/cts-native-scanner/tests/run_unit_tests.sh b/tools/cts-native-scanner/tests/run_unit_tests.sh
deleted file mode 100755
index e85fa7a..0000000
--- a/tools/cts-native-scanner/tests/run_unit_tests.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/bash
-
-# Copyright 2012 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# helper script for running the cts-tradefed unit tests
-
-checkFile() {
- if [ ! -f "$1" ]; then
- echo "Unable to locate $1"
- exit
- fi;
-}
-
-JAR_DIR=${ANDROID_HOST_OUT}/framework
-JARS="ddmlib-prebuilt.jar tradefed.jar hosttestlib.jar cts-native-scanner.jar cts-native-scanner-tests.jar"
-
-for JAR in $JARS; do
- checkFile ${JAR_DIR}/${JAR}
- JAR_PATH=${JAR_PATH}:${JAR_DIR}/${JAR}
-done
-
-java $RDBG_FLAG \
- -cp ${JAR_PATH} com.android.tradefed.command.Console run singleCommand host -n --class com.android.cts.nativescanner.UnitTests "$@"
-
diff --git a/tools/cts-native-scanner/tests/src/com/android/cts/nativescanner/TestScannerTest.java b/tools/cts-native-scanner/tests/src/com/android/cts/nativescanner/TestScannerTest.java
deleted file mode 100644
index b00c7dc..0000000
--- a/tools/cts-native-scanner/tests/src/com/android/cts/nativescanner/TestScannerTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.nativescanner;
-
-import com.android.cts.nativescanner.TestScanner;
-
-import junit.framework.TestCase;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.StringReader;
-import java.util.List;
-import java.util.Iterator;
-
-/**
- * Unit tests for {@link TestScanner}.
- */
-public class TestScannerTest extends TestCase {
-
- public void testSingleTestNamesCase() throws Exception {
- StringReader singleTestString = new StringReader("FakeTestCase.\n FakeTestName\n");
- BufferedReader reader = new BufferedReader(singleTestString);
-
- TestScanner testScanner = new TestScanner(reader, "TestSuite");
-
- List<String> names = testScanner.getTestNames();
- Iterator it = names.iterator();
- assertEquals("suite:TestSuite", it.next());
- assertEquals("case:FakeTestCase", it.next());
- assertEquals("test:FakeTestName", it.next());
- assertFalse(it.hasNext());
- }
-
- public void testMultipleTestNamesCase() throws Exception {
- StringReader singleTestString = new StringReader(
- "Case1.\n Test1\n Test2\nCase2.\n Test3\n Test4\n");
- BufferedReader reader = new BufferedReader(singleTestString);
-
- TestScanner testScanner = new TestScanner(reader, "TestSuite");
-
- List<String> names = testScanner.getTestNames();
- Iterator it = names.iterator();
- assertEquals("suite:TestSuite", it.next());
- assertEquals("case:Case1", it.next());
- assertEquals("test:Test1", it.next());
- assertEquals("test:Test2", it.next());
- assertEquals("case:Case2", it.next());
- assertEquals("test:Test3", it.next());
- assertEquals("test:Test4", it.next());
- assertFalse(it.hasNext());
- }
-
- public void testMissingTestCaseNameCase() {
- StringReader singleTestString = new StringReader(" Test1\n");
- BufferedReader reader = new BufferedReader(singleTestString);
-
- TestScanner testScanner = new TestScanner(reader, "TestSuite");
-
- try {
- List<String> names = testScanner.getTestNames();
- fail();
- } catch (IOException expected) {
- }
- }
-}
diff --git a/tools/cts-native-scanner/tests/src/com/android/cts/nativescanner/UnitTests.java b/tools/cts-native-scanner/tests/src/com/android/cts/nativescanner/UnitTests.java
deleted file mode 100644
index 13d4e5b..0000000
--- a/tools/cts-native-scanner/tests/src/com/android/cts/nativescanner/UnitTests.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.nativescanner;
-
-import com.android.cts.nativescanner.TestScannerTest;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * A test suite for all cts-native-scanner unit tests.
- * <p/>
- * All tests listed here should be self-contained, and do not require any external dependencies
- */
-public class UnitTests extends TestSuite {
-
- public UnitTests() {
- super();
-
- // result package
- addTestSuite(TestScannerTest.class);
- }
-
- public static Test suite() {
- return new UnitTests();
- }
-}
diff --git a/tools/cts-xml-generator/Android.mk b/tools/cts-xml-generator/Android.mk
deleted file mode 100644
index 23256f3..0000000
--- a/tools/cts-xml-generator/Android.mk
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# the hat script
-# ============================================================
-include $(CLEAR_VARS)
-LOCAL_IS_HOST_MODULE := true
-LOCAL_MODULE_CLASS := EXECUTABLES
-LOCAL_MODULE := cts-xml-generator
-LOCAL_SRC_FILES := etc/$(LOCAL_MODULE)
-LOCAL_ADDITIONAL_DEPENDENCIES := $(HOST_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE)$(COMMON_JAVA_PACKAGE_SUFFIX)
-include $(BUILD_PREBUILT)
-
-# the other stuff
-# ============================================================
-subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
- src \
- ))
-
-include $(subdirs)
diff --git a/tools/cts-xml-generator/etc/cts-xml-generator b/tools/cts-xml-generator/etc/cts-xml-generator
deleted file mode 100644
index 5f05af6..0000000
--- a/tools/cts-xml-generator/etc/cts-xml-generator
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2011, The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-libdir=`dirname $progdir`/framework
-
-javaOpts=""
-while expr "x$1" : 'x-J' >/dev/null; do
- opt=`expr "$1" : '-J\(.*\)'`
- javaOpts="${javaOpts} -${opt}"
- shift
-done
-
-exec java $javaOpts -jar $libdir/cts-xml-generator.jar "$@"
diff --git a/tools/cts-xml-generator/src/Android.mk b/tools/cts-xml-generator/src/Android.mk
deleted file mode 100644
index 9e5e646..0000000
--- a/tools/cts-xml-generator/src/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-# cts-xml-generator java library
-# ============================================================
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-LOCAL_MODULE := cts-xml-generator
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_JAVA_LIBRARIES := tradefed
-
-LOCAL_STATIC_JAVA_LIBRARIES := vogarexpectlib compatibility-host-util
-
-include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/cts-xml-generator/src/MANIFEST.mf b/tools/cts-xml-generator/src/MANIFEST.mf
deleted file mode 100644
index ce4178e..0000000
--- a/tools/cts-xml-generator/src/MANIFEST.mf
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: com.android.cts.xmlgenerator.CtsXmlGenerator
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
deleted file mode 100644
index f194edf..0000000
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/CtsXmlGenerator.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.xmlgenerator;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import vogar.ExpectationStore;
-import vogar.ModeId;
-
-import java.io.File;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-
-/** Class that outputs a test package xml. */
-public class CtsXmlGenerator {
-
- private static void usage(String[] args) {
- System.err.println("Arguments: " + Arrays.asList(args));
- System.err.println("Usage: cts-xml-generator -p PACKAGE_NAME -n NAME [-t TEST_TYPE]"
- + " [-j JAR_PATH] [-i INSTRUMENTATION] [-m MANIFEST_FILE] [-e EXPECTATION_FILE]"
- + " [-b UNSUPPORTED_ABI_FILE] [-a ARCHITECTURE] [-o OUTPUT_FILE]"
- + " [-s APP_NAME_SPACE] [-x ADDITIONAL_ATTRIBUTE_KEY->VALUE]");
- System.exit(1);
- }
-
- public static void main(String[] args) throws Exception {
- String appPackageName = null;
- String name = null;
- String outputPath = null;
- Set<File> expectationFiles = new HashSet<File>();
- Set<File> abiFiles = new HashSet<File>();
- String architecture = null;
- File manifestFile = null;
- String instrumentation = null;
- String testType = null;
- String jarPath = null;
- String appNameSpace = null;
- String targetNameSpace = null;
- Map<String, String> additionalAttributes = new HashMap<String, String>();
-
- for (int i = 0; i < args.length; i++) {
- if ("-p".equals(args[i])) {
- appPackageName = getArg(args, ++i, "Missing value for test package");
- } else if ("-n".equals(args[i])) {
- name = getArg(args, ++i, "Missing value for executable name");
- } else if ("-t".equals(args[i])) {
- testType = getArg(args, ++i, "Missing value for test type");
- } else if ("-j".equals(args[i])) {
- jarPath = getArg(args, ++i, "Missing value for jar path");
- } else if ("-m".equals(args[i])) {
- manifestFile = new File(getArg(args, ++i, "Missing value for manifest"));
- } else if ("-i".equals(args[i])) {
- instrumentation = getArg(args, ++i, "Missing value for instrumentation");
- } else if ("-e".equals(args[i])) {
- expectationFiles.add(new File(getArg(args, ++i,
- "Missing value for expectation store")));
- } else if ("-b".equals(args[i])) {
- abiFiles.add(new File(getArg(args, ++i, "Missing value for abi store")));
- } else if ("-a".equals(args[i])) {
- architecture = getArg(args, ++i, "Missing value for architecture");
- } else if ("-o".equals(args[i])) {
- outputPath = getArg(args, ++i, "Missing value for output file");
- } else if ("-s".equals(args[i])) {
- appNameSpace = getArg(args, ++i, "Missing value for app name space");
- } else if ("-r".equals(args[i])) {
- targetNameSpace = getArg(args, ++i, "Missing value for target name space");
- } else if ("-x".equals(args[i])) {
- String value = getArg(args, ++i, "Missing value for additional attribute");
- String[] tokens = value.split("->");
- if (tokens.length != 2) {
- System.err.println(
- "For specifying additional attributes; use the format KEY->VALUE");
- usage(args);
- }
- if (additionalAttributes.containsKey(tokens[0])) {
- System.err.println(String.format(
- "Additional attribute %s has already been specified", tokens[0]));
- usage(args);
- }
- additionalAttributes.put(tokens[0], tokens[1]);
- } else {
- System.err.println("Unsupported flag: " + args[i]);
- usage(args);
- }
- }
-
- String runner = null;
-
- if (manifestFile != null) {
- Document manifest = DocumentBuilderFactory.newInstance().newDocumentBuilder()
- .parse(manifestFile);
- Element documentElement = manifest.getDocumentElement();
- appNameSpace = documentElement.getAttribute("package");
- runner = getElementAttribute(documentElement, "instrumentation",
- "android:name");
- targetNameSpace = getElementAttribute(documentElement, "instrumentation",
- "android:targetPackage");
- }
-
- if (appPackageName == null) {
- System.out.println("Package name is required");
- usage(args);
- } else if (name == null) {
- System.out.println("Executable name is required");
- usage(args);
- }
-
- ExpectationStore failuresStore = ExpectationStore.parse(expectationFiles, ModeId.DEVICE);
- ExpectationStore abiStore = ExpectationStore.parse(abiFiles, ModeId.DEVICE);
- XmlGenerator generator = new XmlGenerator(failuresStore, abiStore, architecture,
- appNameSpace, appPackageName, name, runner, instrumentation, targetNameSpace,
- jarPath, testType, outputPath, additionalAttributes);
- generator.writePackageXml();
- }
-
- private static String getArg(String[] args, int index, String message) {
- if (index < args.length) {
- return args[index];
- } else {
- System.err.println(message);
- usage(args);
- return null;
- }
- }
-
- private static String getElementAttribute(Element parentElement, String elementName,
- String attributeName) {
- NodeList nodeList = parentElement.getElementsByTagName(elementName);
- if (nodeList.getLength() > 0) {
- Element element = (Element) nodeList.item(0);
- return element.getAttribute(attributeName);
- }
- return null;
- }
-}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/Test.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/Test.java
deleted file mode 100644
index 93b838b..0000000
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/Test.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.xmlgenerator;
-
-public class Test implements Comparable<Test> {
- private String mName;
- private int mTimeout;
-
- public Test(String name, int timeout) {
- mName = name;
- mTimeout = timeout;
- }
-
- public String getName() {
- return mName;
- }
-
- public int getTimeout() {
- return mTimeout;
- }
-
- @Override
- public int compareTo(Test another) {
- return getName().compareTo(another.getName());
- }
-}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java
deleted file mode 100644
index c680c2a..0000000
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestCase.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.xmlgenerator;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-class TestCase implements Comparable<TestCase> {
-
- private final String mName;
-
- private final List<Test> mTests = new ArrayList<Test>();
-
- public TestCase(String name) {
- mName = name;
- }
-
- public String getName() {
- return mName;
- }
-
- public void addTest(String testName, int timeout) {
- mTests.add(new Test(testName, timeout));
- }
-
- public Collection<Test> getTests() {
- return Collections.unmodifiableCollection(mTests);
- }
-
- @Override
- public int compareTo(TestCase another) {
- return getName().compareTo(another.getName());
- }
-
- public int countTests() {
- return mTests.size();
- }
-}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestListParser.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestListParser.java
deleted file mode 100644
index c77d1a0..0000000
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestListParser.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.xmlgenerator;
-
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Scanner;
-
-/**
- * Parser of test lists that are in the format of:
- *
- * suite:android.holo.cts
- * case:HoloTest
- * test:testHolo
- * test:testHoloDialog[:timeout_value]
- */
-class TestListParser {
-
- public Collection<TestSuite> parse(InputStream input) {
- Map<String, TestSuite> suiteMap = new HashMap<String, TestSuite>();
- TestSuite currentSuite = null;
- TestCase currentCase = null;
- Scanner scanner = null;
- try {
- scanner = new Scanner(input);
- while(scanner.hasNextLine()) {
- String line = scanner.nextLine();
- String[] tokens = line.split(":");
- if (tokens.length < 2) {
- continue;
- }
-
- String key = tokens[0];
- String value = tokens[1];
- if ("suite".equals(key)) {
- currentSuite = handleSuite(suiteMap, value);
- } else if ("case".equals(key)) {
- currentCase = handleCase(currentSuite, value);
- } else if ("test".equals(key)) {
- int timeout = -1;
- if (tokens.length == 3) {
- timeout = Integer.parseInt(tokens[2]);
- }
- handleTest(currentCase, value, timeout);
- }
- }
- } finally {
- if (scanner != null) {
- scanner.close();
- }
- }
- return suiteMap.values();
- }
-
- private TestSuite handleSuite(Map<String, TestSuite> suiteMap, String fullSuite) {
- String[] suites = fullSuite.split("\\.");
- int numSuites = suites.length;
- TestSuite lastSuite = null;
-
- for (int i = 0; i < numSuites; i++) {
- String name = suites[i];
- if (lastSuite != null) {
- if (lastSuite.hasSuite(name)) {
- lastSuite = lastSuite.getSuite(name);
- } else {
- TestSuite newSuite = new TestSuite(name);
- lastSuite.addSuite(newSuite);
- lastSuite = newSuite;
- }
- } else if (suiteMap.containsKey(name)) {
- lastSuite = suiteMap.get(name);
- } else {
- lastSuite = new TestSuite(name);
- suiteMap.put(name, lastSuite);
- }
- }
-
- return lastSuite;
- }
-
- private TestCase handleCase(TestSuite suite, String caseName) {
- TestCase testCase = new TestCase(caseName);
- suite.addCase(testCase);
- return testCase;
- }
-
- private void handleTest(TestCase testCase, String test, int timeout) {
- testCase.addTest(test, timeout);
- }
-}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestSuite.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestSuite.java
deleted file mode 100644
index 1d71e1f..0000000
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/TestSuite.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.cts.xmlgenerator;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-class TestSuite implements Comparable<TestSuite> {
-
- private final String mName;
-
- private final Map<String, TestSuite> mSuites = new HashMap<String, TestSuite>();
-
- private final List<TestCase> mCases = new ArrayList<TestCase>();
-
- public TestSuite(String name) {
- mName = name;
- }
-
- public String getName() {
- return mName;
- }
-
- public boolean hasSuite(String name) {
- return mSuites.containsKey(name);
- }
-
- public TestSuite getSuite(String name) {
- return mSuites.get(name);
- }
-
- public void addSuite(TestSuite suite) {
- mSuites.put(suite.mName, suite);
- }
-
- public Collection<TestSuite> getSuites() {
- return Collections.unmodifiableCollection(mSuites.values());
- }
-
- public void addCase(TestCase testCase) {
- mCases.add(testCase);
- }
-
- public Collection<TestCase> getCases() {
- return Collections.unmodifiableCollection(mCases);
- }
-
- @Override
- public int compareTo(TestSuite another) {
- return getName().compareTo(another.getName());
- }
-
- public int countTests() {
- int count = 0;
- for (TestSuite suite : mSuites.values()) {
- count += suite.countTests();
- }
- for (TestCase testCase : mCases) {
- count += testCase.countTests();
- }
- return count;
- }
-}
diff --git a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java b/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
deleted file mode 100644
index bf1a1ab..0000000
--- a/tools/cts-xml-generator/src/com/android/cts/xmlgenerator/XmlGenerator.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.cts.xmlgenerator;
-
-import vogar.Expectation;
-import vogar.ExpectationStore;
-import vogar.Result;
-
-import com.android.tradefed.util.AbiUtils;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Generator of TestPackage XML files for native tests.
- *
- * It takes in an input of the following form:
- *
- * suite: x.y.z
- * case:TestClass1
- * test:testMethod1
- * test:testMethod2
- * case:TestClass2
- * test:testMethod1
- * suite: x.y
- * case:TestClass3
- * test:testMethod2
- */
-class XmlGenerator {
-
- /** Example: com.android.cts.holo */
- private final String mAppNamespace;
-
- /** Test package name like "android.nativemedia" to group the tests. */
- private final String mAppPackageName;
-
- /** Name of the native executable. */
- private final String mName;
-
- /** Test runner */
- private final String mRunner;
-
- private final String mTargetBinaryName;
-
- private final String mTargetNameSpace;
-
- private final String mJarPath;
-
- private final String mTestType;
-
- /** Path to output file or null to just dump to standard out. */
- private final String mOutputPath;
-
- /** ExpectationStore to filter out known failures. */
- private final ExpectationStore mKnownFailures;
-
- /** ExpectationStore to filter out unsupported abis. */
- private final ExpectationStore mUnsupportedAbis;
-
- private final String mArchitecture;
-
- private final Map<String, String> mAdditionalAttributes;
-
- XmlGenerator(ExpectationStore knownFailures, ExpectationStore unsupportedAbis,
- String architecture, String appNameSpace, String appPackageName, String name,
- String runner, String targetBinaryName, String targetNameSpace, String jarPath,
- String testType, String outputPath, Map<String, String> additionalAttributes) {
- mAppNamespace = appNameSpace;
- mAppPackageName = appPackageName;
- mName = name;
- mRunner = runner;
- mTargetBinaryName = targetBinaryName;
- mTargetNameSpace = targetNameSpace;
- mJarPath = jarPath;
- mTestType = testType;
- mOutputPath = outputPath;
- mKnownFailures = knownFailures;
- mUnsupportedAbis = unsupportedAbis;
- mArchitecture = architecture;
- mAdditionalAttributes = additionalAttributes;
- }
-
- public void writePackageXml() throws IOException {
- OutputStream output = System.out;
- if (mOutputPath != null) {
- File outputFile = new File(mOutputPath);
- output = new FileOutputStream(outputFile);
- }
-
- PrintWriter writer = null;
- try {
- writer = new PrintWriter(output);
- writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
- writeTestPackage(writer);
- } finally {
- if (writer != null) {
- writer.close();
- }
- }
- }
-
- private void writeTestPackage(PrintWriter writer) {
- writer.append("<TestPackage");
- if (mAppNamespace != null) {
- writer.append(" appNameSpace=\"").append(mAppNamespace).append("\"");
- }
-
- writer.append(" appPackageName=\"").append(mAppPackageName).append("\"");
- writer.append(" name=\"").append(mName).append("\"");
-
- if (mRunner != null) {
- writer.append(" runner=\"").append(mRunner).append("\"");
- }
-
- if (mAppNamespace != null && mTargetNameSpace != null
- && !mAppNamespace.equals(mTargetNameSpace)) {
- writer.append(" targetBinaryName=\"").append(mTargetBinaryName).append("\"");
- writer.append(" targetNameSpace=\"").append(mTargetNameSpace).append("\"");
- }
-
- if (mTestType != null && !mTestType.isEmpty()) {
- writer.append(" testType=\"").append(mTestType).append("\"");
- }
-
- if (mJarPath != null) {
- writer.append(" jarPath=\"").append(mJarPath).append("\"");
- }
-
- for (Map.Entry<String, String> entry : mAdditionalAttributes.entrySet()) {
- writer.append(String.format(" %s=\"%s\"", entry.getKey(), entry.getValue()));
- }
-
- writer.println(" version=\"1.0\">");
-
- TestListParser parser = new TestListParser();
- Collection<TestSuite> suites = parser.parse(System.in);
- StringBuilder nameCollector = new StringBuilder();
- writeTestSuites(writer, suites, nameCollector);
- writer.println("</TestPackage>");
- }
-
- private void writeTestSuites(PrintWriter writer, Collection<TestSuite> suites,
- StringBuilder nameCollector) {
- Collection<TestSuite> sorted = sortCollection(suites);
- for (TestSuite suite : sorted) {
- if (suite.countTests() == 0) {
- continue;
- }
- writer.append("<TestSuite name=\"").append(suite.getName()).println("\">");
-
- String namePart = suite.getName();
- if (nameCollector.length() > 0) {
- namePart = "." + namePart;
- }
- nameCollector.append(namePart);
-
- writeTestSuites(writer, suite.getSuites(), nameCollector);
- writeTestCases(writer, suite.getCases(), nameCollector);
-
- nameCollector.delete(nameCollector.length() - namePart.length(),
- nameCollector.length());
- writer.println("</TestSuite>");
- }
- }
-
- private void writeTestCases(PrintWriter writer, Collection<TestCase> cases,
- StringBuilder nameCollector) {
- Collection<TestCase> sorted = sortCollection(cases);
- for (TestCase testCase : sorted) {
- if (testCase.countTests() == 0) {
- continue;
- }
- String name = testCase.getName();
- writer.append("<TestCase name=\"").append(name).println("\">");
- nameCollector.append('.').append(name);
-
- writeTests(writer, testCase.getTests(), nameCollector);
-
- nameCollector.delete(nameCollector.length() - name.length() - 1,
- nameCollector.length());
- writer.println("</TestCase>");
- }
- }
-
- private void writeTests(PrintWriter writer, Collection<Test> tests,
- StringBuilder nameCollector) {
- Collection<Test> sorted = sortCollection(tests);
- for (Test test : sorted) {
- String className = nameCollector.toString();
- nameCollector.append('#').append(test.getName());
- writer.append("<Test name=\"").append(test.getName()).append("\"");
- String abis = getSupportedAbis(mUnsupportedAbis, mArchitecture,
- className, nameCollector.toString()).toString();
- writer.append(" abis=\"" + abis.substring(1, abis.length() - 1) + "\"");
- if (isKnownFailure(mKnownFailures, nameCollector.toString())) {
- writer.append(" expectation=\"failure\"");
- }
- if (test.getTimeout() >= 0) {
- writer.append(" timeout=\"" + test.getTimeout() + "\"");
- }
- writer.println(" />");
-
- nameCollector.delete(nameCollector.length() - test.getName().length() - 1,
- nameCollector.length());
- }
- }
-
- private <E extends Comparable<E>> Collection<E> sortCollection(Collection<E> col) {
- List<E> list = new ArrayList<E>(col);
- Collections.sort(list);
- return list;
- }
-
- public static boolean isKnownFailure(ExpectationStore expectationStore, String testName) {
- return expectationStore != null
- && expectationStore.get(testName).getResult() != Result.SUCCESS;
- }
-
- // Returns the list of ABIs supported by this TestCase on this architecture.
- public static Set<String> getSupportedAbis(ExpectationStore expectationStore,
- String architecture, String className, String testName) {
- Set<String> supportedAbis = AbiUtils.getAbisForArch(architecture);
- if (expectationStore == null) {
- return supportedAbis;
- }
-
- removeUnsupportedAbis(expectationStore.get(className), supportedAbis);
- removeUnsupportedAbis(expectationStore.get(testName), supportedAbis);
- return supportedAbis;
- }
-
- public static void removeUnsupportedAbis(Expectation expectation, Set<String> supportedAbis) {
- if (expectation == null) {
- return;
- }
-
- String description = expectation.getDescription();
- if (description.isEmpty()) {
- return;
- }
-
- String[] unsupportedAbis = description.split(":")[1].split(",");
- for (String a : unsupportedAbis) {
- String abi = a.trim();
- if (!AbiUtils.isAbiSupportedByCompatibility(abi)) {
- throw new RuntimeException(
- String.format("Unrecognised ABI %s in %s", abi, description));
- }
- supportedAbis.remove(abi);
- }
- }
-
-}
diff --git a/tools/junit/Android.mk b/tools/junit/Android.mk
index b581149..bc507c1 100644
--- a/tools/junit/Android.mk
+++ b/tools/junit/Android.mk
@@ -18,6 +18,6 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_MODULE := cts-junit
LOCAL_MODULE_TAGS := optional
-LOCAL_STATIC_JAVA_LIBRARIES := junit4-target
+LOCAL_STATIC_JAVA_LIBRARIES := junit
LOCAL_DEX_PREOPT := false
include $(BUILD_JAVA_LIBRARY)
diff --git a/tools/selinux/SELinuxNeverallowTestFrame.py b/tools/selinux/SELinuxNeverallowTestFrame.py
index 51ecc2c..31ee446 100644
--- a/tools/selinux/SELinuxNeverallowTestFrame.py
+++ b/tools/selinux/SELinuxNeverallowTestFrame.py
@@ -18,6 +18,7 @@
package android.cts.security;
+import android.platform.test.annotations.RestrictedBuildTest;
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.device.ITestDevice;
@@ -78,6 +79,7 @@
"""
src_method = """
+ @RestrictedBuildTest
public void testNeverallowRules() throws Exception {
String neverallowRule = "$NEVERALLOW_RULE_HERE$";
diff --git a/tools/utils/Android.mk b/tools/utils/Android.mk
index 6a77928..6b01e57 100644
--- a/tools/utils/Android.mk
+++ b/tools/utils/Android.mk
@@ -24,7 +24,7 @@
LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
-LOCAL_JAVA_LIBRARIES := junit tradefed
+LOCAL_JAVA_LIBRARIES := junit-host tradefed
LOCAL_STATIC_JAVA_LIBRARIES := compatibility-host-util vogarexpectlib
include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/vm-tests-tf/Android.mk b/tools/vm-tests-tf/Android.mk
index 4935b5e..6d47303 100644
--- a/tools/vm-tests-tf/Android.mk
+++ b/tools/vm-tests-tf/Android.mk
@@ -24,7 +24,7 @@
LOCAL_MODULE := cts-tf-dalvik-lib
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := junit-targetdex
+LOCAL_JAVA_LIBRARIES := junit
include $(BUILD_JAVA_LIBRARY)