diff options
60 files changed, 1627 insertions, 1389 deletions
diff --git a/hostsidetests/jdwptunnel/OWNERS b/hostsidetests/jdwptunnel/OWNERS new file mode 100644 index 00000000000..6e0629999c7 --- /dev/null +++ b/hostsidetests/jdwptunnel/OWNERS @@ -0,0 +1,2 @@ +# Bug component: 86431 +include /hostsidetests/jvmti/run-tests/OWNERS diff --git a/tests/JobSchedulerSharedUid/Android.bp b/tests/JobSchedulerSharedUid/Android.bp new file mode 100644 index 00000000000..1320dc2efa8 --- /dev/null +++ b/tests/JobSchedulerSharedUid/Android.bp @@ -0,0 +1,39 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +android_test { + name: "CtsJobSchedulerSharedUidTestCases", + defaults: ["cts_defaults"], + static_libs: [ + "compatibility-device-util-axt", + "ub-uiautomator", + "androidx.test.rules", + ], + libs: ["android.test.base.stubs"], + srcs: [ + "src/**/*.java", + "JobSharedUidTestApp/src/**/*.java", + "jobperm/src/**/*.java", + "shareduid/src/**/*.java", + ], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], + //sdk_version: "current" + platform_apis: true, + +} diff --git a/tests/JobSchedulerSharedUid/Android.mk b/tests/JobSchedulerSharedUid/Android.mk deleted file mode 100755 index 0b9912c9d22..00000000000 --- a/tests/JobSchedulerSharedUid/Android.mk +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (C) 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -# Don't include this package in any target. -LOCAL_MODULE_TAGS := optional - -# When built, explicitly put it in the data partition. -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util-axt ub-uiautomator androidx.test.rules - -LOCAL_JAVA_LIBRARIES := android.test.base.stubs - -LOCAL_SRC_FILES := $(call all-java-files-under, src) -LOCAL_SRC_FILES += $(call all-java-files-under, JobSharedUidTestApp/src) -LOCAL_SRC_FILES += $(call all-java-files-under, jobperm/src) -LOCAL_SRC_FILES += $(call all-java-files-under, shareduid/src) - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -# Must match the package name in CtsTestCaseList.mk -LOCAL_PACKAGE_NAME := CtsJobSchedulerSharedUidTestCases - -#LOCAL_SDK_VERSION := current -LOCAL_PRIVATE_PLATFORM_APIS := true - -include $(BUILD_CTS_PACKAGE) - -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/JobSchedulerSharedUid/JobSharedUidTestApp/Android.bp b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/Android.bp new file mode 100644 index 00000000000..6ff76daf885 --- /dev/null +++ b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/Android.bp @@ -0,0 +1,26 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +android_test_helper_app { + name: "CtsJobSharedUidTestApp", + defaults: ["cts_defaults"], + srcs: ["src/**/*.java"], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], + sdk_version: "current", +} diff --git a/tests/JobSchedulerSharedUid/JobSharedUidTestApp/Android.mk b/tests/JobSchedulerSharedUid/JobSharedUidTestApp/Android.mk deleted file mode 100644 index f3d36db070c..00000000000 --- a/tests/JobSchedulerSharedUid/JobSharedUidTestApp/Android.mk +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 - -LOCAL_SRC_FILES := \ - $(call all-java-files-under, src) \ - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -LOCAL_PACKAGE_NAME := CtsJobSharedUidTestApp -LOCAL_SDK_VERSION := current - -include $(BUILD_CTS_PACKAGE) diff --git a/tests/JobSchedulerSharedUid/jobperm/Android.bp b/tests/JobSchedulerSharedUid/jobperm/Android.bp new file mode 100644 index 00000000000..9ac380c6f94 --- /dev/null +++ b/tests/JobSchedulerSharedUid/jobperm/Android.bp @@ -0,0 +1,27 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +android_test_helper_app { + name: "CtsJobSchedulerJobPerm", + defaults: ["cts_defaults"], + static_libs: ["compatibility-device-util-axt"], + srcs: ["src/**/*.java"], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], + platform_apis: true, +} diff --git a/tests/JobSchedulerSharedUid/jobperm/Android.mk b/tests/JobSchedulerSharedUid/jobperm/Android.mk deleted file mode 100644 index 44ecdf32dbd..00000000000 --- a/tests/JobSchedulerSharedUid/jobperm/Android.mk +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (C) 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 - -LOCAL_STATIC_JAVA_LIBRARIES := \ - compatibility-device-util-axt \ - -LOCAL_SRC_FILES := \ - $(call all-java-files-under, src) \ - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -LOCAL_PACKAGE_NAME := CtsJobSchedulerJobPerm -LOCAL_PRIVATE_PLATFORM_APIS := true - -include $(BUILD_CTS_PACKAGE) diff --git a/tests/JobSchedulerSharedUid/shareduid/Android.bp b/tests/JobSchedulerSharedUid/shareduid/Android.bp new file mode 100644 index 00000000000..68ed7f5a5e9 --- /dev/null +++ b/tests/JobSchedulerSharedUid/shareduid/Android.bp @@ -0,0 +1,27 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +android_test_helper_app { + name: "CtsJobSchedulerSharedUid", + defaults: ["cts_defaults"], + static_libs: ["compatibility-device-util-axt"], + srcs: ["src/**/*.java"], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], + sdk_version: "test_current", +} diff --git a/tests/JobSchedulerSharedUid/shareduid/Android.mk b/tests/JobSchedulerSharedUid/shareduid/Android.mk deleted file mode 100644 index cfc89cdeec9..00000000000 --- a/tests/JobSchedulerSharedUid/shareduid/Android.mk +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (C) 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 - -LOCAL_STATIC_JAVA_LIBRARIES := \ - compatibility-device-util-axt \ - -LOCAL_SRC_FILES := \ - $(call all-java-files-under, src) \ - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -LOCAL_PACKAGE_NAME := CtsJobSchedulerSharedUid -LOCAL_SDK_VERSION := current - -include $(BUILD_CTS_PACKAGE) diff --git a/tests/signature/Android.bp b/tests/signature/Android.bp index 21344ea9dfc..5cadd8889c3 100644 --- a/tests/signature/Android.bp +++ b/tests/signature/Android.bp @@ -14,6 +14,9 @@ // Compat. java_library_host { - name: "signature-hostside", - static_libs: ["signature-common-javalib"], + name: "signature-hostside", + visibility: [ + "//cts/tests/signature/tests", + ], + static_libs: ["signature-common-javalib"], } diff --git a/tests/signature/api-check/android-test-base-28-api/Android.mk b/tests/signature/api-check/android-test-base-28-api/Android.mk index 02f3a50b58f..1b698ad7cce 100644 --- a/tests/signature/api-check/android-test-base-28-api/Android.mk +++ b/tests/signature/api-check/android-test-base-28-api/Android.mk @@ -21,7 +21,7 @@ LOCAL_PACKAGE_NAME := CtsAndroidTestBase28ApiSignatureTestCases LOCAL_SIGNATURE_API_FILES := \ android-test-base-current.api \ -LOCAL_MIN_SDK_VERSION := 25 +LOCAL_MIN_SDK_VERSION := 27 LOCAL_SDK_VERSION := 28 include $(LOCAL_PATH)/../build_signature_apk.mk diff --git a/tests/signature/api-check/android-test-base-28-api/AndroidManifest.xml b/tests/signature/api-check/android-test-base-28-api/AndroidManifest.xml index e5f1269b855..1ed4315f2cf 100644 --- a/tests/signature/api-check/android-test-base-28-api/AndroidManifest.xml +++ b/tests/signature/api-check/android-test-base-28-api/AndroidManifest.xml @@ -20,7 +20,7 @@ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> - <uses-sdk android:minSdkVersion="25" android:targetSdkVersion="28"/> + <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="28"/> <application android:debuggable="true" android:extractNativeLibs="true" diff --git a/tests/signature/api-check/apache-http-legacy-27-api/Android.mk b/tests/signature/api-check/apache-http-legacy-27-api/Android.mk index 906dda807bc..698fe4f1387 100644 --- a/tests/signature/api-check/apache-http-legacy-27-api/Android.mk +++ b/tests/signature/api-check/apache-http-legacy-27-api/Android.mk @@ -22,6 +22,6 @@ LOCAL_SIGNATURE_API_FILES := \ current.api \ apache-http-legacy-current.api \ -LOCAL_MIN_SDK_VERSION := 22 +LOCAL_MIN_SDK_VERSION := 27 include $(LOCAL_PATH)/../build_signature_apk.mk diff --git a/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml b/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml index 8044d4b0176..8a789d91a9b 100644 --- a/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml +++ b/tests/signature/api-check/apache-http-legacy-27-api/AndroidManifest.xml @@ -20,7 +20,7 @@ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> - <uses-sdk android:minSdkVersion="22" android:targetSdkVersion="27"/> + <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="27"/> <application android:extractNativeLibs="true" android:largeHeap="true"/> diff --git a/tests/signature/api-check/hidden-api-blacklist-27-api/Android.mk b/tests/signature/api-check/hidden-api-blacklist-27-api/Android.mk index 59f7d6f2144..a663264dd14 100644 --- a/tests/signature/api-check/hidden-api-blacklist-27-api/Android.mk +++ b/tests/signature/api-check/hidden-api-blacklist-27-api/Android.mk @@ -19,4 +19,5 @@ LOCAL_PACKAGE_NAME := CtsHiddenApiBlacklistApi27TestCases LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) LOCAL_SIGNATURE_API_FILES := hiddenapi_flags.csv LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker +LOCAL_MIN_SDK_VERSION := 27 include $(LOCAL_PATH)/../build_signature_apk.mk diff --git a/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml index c714e97a3dc..cd3949e868c 100644 --- a/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml +++ b/tests/signature/api-check/hidden-api-blacklist-27-api/AndroidManifest.xml @@ -19,7 +19,7 @@ package="android.signature.cts.api.hiddenapi_blacklist_api_27"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> - <uses-sdk android:targetSdkVersion="27" /> + <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="27" /> <application android:extractNativeLibs="true" android:largeHeap="true"/> diff --git a/tests/signature/api-check/hidden-api-blacklist-28-api/Android.mk b/tests/signature/api-check/hidden-api-blacklist-28-api/Android.mk index f1cd2f3aa6a..a053bda992c 100644 --- a/tests/signature/api-check/hidden-api-blacklist-28-api/Android.mk +++ b/tests/signature/api-check/hidden-api-blacklist-28-api/Android.mk @@ -19,4 +19,5 @@ LOCAL_PACKAGE_NAME := CtsHiddenApiBlacklistApi28TestCases LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) LOCAL_SIGNATURE_API_FILES := hiddenapi_flags.csv LOCAL_JNI_SHARED_LIBRARIES := libcts_dexchecker +LOCAL_MIN_SDK_VERSION := 27 include $(LOCAL_PATH)/../build_signature_apk.mk diff --git a/tests/signature/api-check/hidden-api-blacklist-28-api/AndroidManifest.xml b/tests/signature/api-check/hidden-api-blacklist-28-api/AndroidManifest.xml index d011b88990d..cb1c4bc0352 100644 --- a/tests/signature/api-check/hidden-api-blacklist-28-api/AndroidManifest.xml +++ b/tests/signature/api-check/hidden-api-blacklist-28-api/AndroidManifest.xml @@ -19,7 +19,7 @@ package="android.signature.cts.api.hiddenapi_blacklist_api_28"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> - <uses-sdk android:targetSdkVersion="28" /> + <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="28" /> <application android:extractNativeLibs="true" android:largeHeap="true"/> diff --git a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java index 7861df71ccb..9083f0cf811 100644 --- a/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java +++ b/tests/signature/api-check/src/java/android/signature/cts/api/SignatureTest.java @@ -23,13 +23,11 @@ import android.signature.cts.ClassProvider; import android.signature.cts.FailureType; import android.signature.cts.JDiffClassDescription; import android.signature.cts.ReflectionHelper; -import java.io.IOException; import java.util.Comparator; import java.util.Set; import java.util.TreeSet; import java.util.function.Predicate; import java.util.stream.Collectors; -import org.xmlpull.v1.XmlPullParserException; /** * Performs the signature check via a JUnit test. @@ -97,9 +95,7 @@ public class SignatureTest extends AbstractApiTest { } } - private Set<JDiffClassDescription> loadUnexpectedClasses() - throws IOException, XmlPullParserException { - + private Set<JDiffClassDescription> loadUnexpectedClasses() { ApiDocumentParser apiDocumentParser = new ApiDocumentParser(TAG); return parseApiFilesAsStream(apiDocumentParser, unexpectedApiFiles) .collect(Collectors.toCollection(SignatureTest::newSetOfClassDescriptions)); @@ -109,11 +105,8 @@ public class SignatureTest extends AbstractApiTest { return new TreeSet<>(Comparator.comparing(JDiffClassDescription::getAbsoluteClassName)); } - private void loadBaseClasses(ApiComplianceChecker complianceChecker) - throws IOException, XmlPullParserException { - - ApiDocumentParser apiDocumentParser = - new ApiDocumentParser(TAG); + private void loadBaseClasses(ApiComplianceChecker complianceChecker) { + ApiDocumentParser apiDocumentParser = new ApiDocumentParser(TAG); parseApiFilesAsStream(apiDocumentParser, baseApiFiles) .forEach(complianceChecker::addBaseClass); } diff --git a/tests/signature/api-check/system-annotation/Android.mk b/tests/signature/api-check/system-annotation/Android.mk index 680e4222855..429f5f82b6c 100644 --- a/tests/signature/api-check/system-annotation/Android.mk +++ b/tests/signature/api-check/system-annotation/Android.mk @@ -25,4 +25,5 @@ LOCAL_SIGNATURE_API_FILES := \ car-system-current.api \ car-system-removed.api \ +LOCAL_MIN_SDK_VERSION := 27 include $(LOCAL_PATH)/../build_signature_apk.mk diff --git a/tests/signature/api-check/system-annotation/AndroidManifest.xml b/tests/signature/api-check/system-annotation/AndroidManifest.xml index 34a12c42f0e..0a254e357df 100644 --- a/tests/signature/api-check/system-annotation/AndroidManifest.xml +++ b/tests/signature/api-check/system-annotation/AndroidManifest.xml @@ -20,7 +20,7 @@ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> - <uses-sdk android:targetSdkVersion="28" /> + <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="28" /> <application android:debuggable="true" android:extractNativeLibs="true" diff --git a/tests/signature/intent-check/AndroidTest.xml b/tests/signature/intent-check/AndroidTest.xml index e76cd796e41..f54655898b8 100644 --- a/tests/signature/intent-check/AndroidTest.xml +++ b/tests/signature/intent-check/AndroidTest.xml @@ -49,6 +49,7 @@ </target_preparer> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > <option name="package" value="android.signature.cts.intent" /> + <option name="class" value="android.signature.cts.intent.IntentTest" /> <option name="runtime-hint" value="10s" /> <!-- disable isolated storage so tests can access dynamic config stored in /sdcard. --> <option name="isolated-storage" value="false" /> diff --git a/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java b/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java index 3ccf7a0b858..7cbfaad5f19 100644 --- a/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java +++ b/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java @@ -15,13 +15,10 @@ */ package android.signature.cts.intent; -import static android.signature.cts.CurrentApi.CURRENT_API_FILE; -import static android.signature.cts.CurrentApi.SYSTEM_CURRENT_API_FILE; -import static android.signature.cts.CurrentApi.SYSTEM_REMOVED_API_FILE; - import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.signature.cts.ApiDocumentParser; +import android.signature.cts.CurrentApi; import android.signature.cts.JDiffClassDescription.JDiffField; import android.signature.cts.VirtualPath; import android.util.Log; @@ -50,6 +47,16 @@ import java.util.Set; */ @RunWith(AndroidJUnit4.class) public class IntentTest { + + private static final String CURRENT_API_FILE = + CurrentApi.API_FILE_DIRECTORY + "/current.api"; + + private static final String SYSTEM_CURRENT_API_FILE = + CurrentApi.API_FILE_DIRECTORY + "/system-current.api"; + + private static final String SYSTEM_REMOVED_API_FILE = + CurrentApi.API_FILE_DIRECTORY + "/system-removed.api"; + private static final String TAG = IntentTest.class.getSimpleName(); private static final File SIGNATURE_TEST_PACKGES = diff --git a/tests/signature/lib/android/Android.bp b/tests/signature/lib/android/Android.bp index 206dd2796a9..cb38ada8eec 100644 --- a/tests/signature/lib/android/Android.bp +++ b/tests/signature/lib/android/Android.bp @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -java_library_static { - name: "cts-signature-common", - visibility: [ - "//cts/tests/signature:__subpackages__", - ], - host_supported: false, - installable: false, - srcs: ["src/**/*.java"], - static_libs: ["signature-common-javalib"], - sdk_version: "current", +java_library { + name: "cts-signature-common", + visibility: [ + "//cts/tests/signature:__subpackages__", + ], + installable: false, + srcs: ["src/**/*.java"], + static_libs: [ + "signature-common-javalib", + ], + sdk_version: "current", } diff --git a/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java b/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java index 68c0be83c8d..4a5c5047dbf 100644 --- a/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java +++ b/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java @@ -15,31 +15,8 @@ */ package android.signature.cts; -import static android.signature.cts.CurrentApi.ATTRIBUTE_NAME; -import static android.signature.cts.CurrentApi.ATTRIBUTE_TYPE; -import static android.signature.cts.CurrentApi.TAG_CLASS; -import static android.signature.cts.CurrentApi.TAG_CONSTRUCTOR; -import static android.signature.cts.CurrentApi.TAG_EXCEPTION; -import static android.signature.cts.CurrentApi.TAG_FIELD; -import static android.signature.cts.CurrentApi.TAG_IMPLEMENTS; -import static android.signature.cts.CurrentApi.TAG_INTERFACE; -import static android.signature.cts.CurrentApi.TAG_METHOD; -import static android.signature.cts.CurrentApi.TAG_PACKAGE; -import static android.signature.cts.CurrentApi.TAG_PARAM; -import static android.signature.cts.CurrentApi.TAG_ROOT; - -import android.util.Log; -import java.io.IOException; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.Spliterator; -import java.util.function.Consumer; import java.util.stream.Stream; -import java.util.stream.StreamSupport; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; + /** * Parses an XML api definition file and constructs and populates an {@link JDiffClassDescription} @@ -49,185 +26,23 @@ import org.xmlpull.v1.XmlPullParserFactory; */ public class ApiDocumentParser { - private static final Set<String> KEY_TAG_SET; - static { - KEY_TAG_SET = new HashSet<>(); - Collections.addAll(KEY_TAG_SET, - TAG_PACKAGE, - TAG_CLASS, - TAG_INTERFACE, - TAG_IMPLEMENTS, - TAG_CONSTRUCTOR, - TAG_METHOD, - TAG_PARAM, - TAG_EXCEPTION, - TAG_FIELD); - } - private final String tag; - private final XmlPullParserFactory factory; - public ApiDocumentParser(String tag) { this.tag = tag; - try { - factory = XmlPullParserFactory.newInstance(); - } catch (XmlPullParserException e) { - throw new RuntimeException(e); - } } - public Stream<JDiffClassDescription> parseAsStream(VirtualPath path) { - XmlPullParser parser; - try { - parser = factory.newPullParser(); - parser.setInput(path.newInputStream(), null); - return StreamSupport.stream(new ClassDescriptionSpliterator(parser), false); - } catch (XmlPullParserException | IOException e) { - throw new RuntimeException("Could not parse " + path, e); + private ApiParser getApiParser(VirtualPath path) { + if (path.toString().endsWith(".api")) { + return new XmlApiParser(tag); + } else { + throw new IllegalStateException("Unrecognized file type: " + path); } } - private class ClassDescriptionSpliterator implements Spliterator<JDiffClassDescription> { - - private final XmlPullParser parser; - - JDiffClassDescription currentClass = null; - String currentPackage = ""; - JDiffClassDescription.JDiffMethod currentMethod = null; - - ClassDescriptionSpliterator(XmlPullParser parser) throws IOException, XmlPullParserException { - this.parser = parser; - logd(String.format("Name: %s", parser.getName())); - logd(String.format("Text: %s", parser.getText())); - logd(String.format("Namespace: %s", parser.getNamespace())); - logd(String.format("Line Number: %s", parser.getLineNumber())); - logd(String.format("Column Number: %s", parser.getColumnNumber())); - logd(String.format("Position Description: %s", parser.getPositionDescription())); - beginDocument(parser, TAG_ROOT); - } - - @Override - public boolean tryAdvance(Consumer<? super JDiffClassDescription> action) { - JDiffClassDescription classDescription; - try { - classDescription = next(); - } catch (IOException|XmlPullParserException e) { - throw new RuntimeException(e); - } - - if (classDescription == null) { - return false; - } - action.accept(classDescription); - return true; - } - - @Override - public Spliterator<JDiffClassDescription> trySplit() { - return null; - } - - @Override - public long estimateSize() { - return Long.MAX_VALUE; - } - - @Override - public int characteristics() { - return ORDERED | DISTINCT | NONNULL | IMMUTABLE; - } - - private void beginDocument(XmlPullParser parser, String firstElementName) - throws XmlPullParserException, IOException { - int type; - do { - type = parser.next(); - } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT); - - if (type != XmlPullParser.START_TAG) { - throw new XmlPullParserException("No start tag found"); - } - - if (!parser.getName().equals(firstElementName)) { - throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() + - ", expected " + firstElementName); - } - } - - private JDiffClassDescription next() throws IOException, XmlPullParserException { - int type; - while (true) { - do { - type = parser.next(); - } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT - && type != XmlPullParser.END_TAG); - - if (type == XmlPullParser.END_DOCUMENT) { - logd("Reached end of document"); - break; - } - - String tagname = parser.getName(); - if (type == XmlPullParser.END_TAG) { - if (TAG_CLASS.equals(tagname) || TAG_INTERFACE.equals(tagname)) { - logd("Reached end of class: " + currentClass); - return currentClass; - } else if (TAG_PACKAGE.equals(tagname)) { - currentPackage = ""; - } - continue; - } - - if (!KEY_TAG_SET.contains(tagname)) { - continue; - } - - if (tagname.equals(TAG_PACKAGE)) { - currentPackage = parser.getAttributeValue(null, ATTRIBUTE_NAME); - } else if (tagname.equals(TAG_CLASS)) { - currentClass = CurrentApi.loadClassInfo( - parser, false, currentPackage); - } else if (tagname.equals(TAG_INTERFACE)) { - currentClass = CurrentApi.loadClassInfo( - parser, true, currentPackage); - } else if (tagname.equals(TAG_IMPLEMENTS)) { - currentClass.addImplInterface(parser.getAttributeValue(null, ATTRIBUTE_NAME)); - } else if (tagname.equals(TAG_CONSTRUCTOR)) { - JDiffClassDescription.JDiffConstructor constructor = - CurrentApi.loadConstructorInfo(parser, currentClass); - currentClass.addConstructor(constructor); - currentMethod = constructor; - } else if (tagname.equals(TAG_METHOD)) { - currentMethod = CurrentApi.loadMethodInfo(currentClass.getClassName(), parser); - currentClass.addMethod(currentMethod); - } else if (tagname.equals(TAG_PARAM)) { - currentMethod.addParam(parser.getAttributeValue(null, ATTRIBUTE_TYPE)); - } else if (tagname.equals(TAG_EXCEPTION)) { - currentMethod.addException(parser.getAttributeValue(null, ATTRIBUTE_TYPE)); - } else if (tagname.equals(TAG_FIELD)) { - JDiffClassDescription.JDiffField field = CurrentApi.loadFieldInfo(currentClass.getClassName(), parser); - currentClass.addField(field); - } else { - throw new RuntimeException( - "unknown tag exception:" + tagname); - } - if (currentPackage != null) { - logd(String.format("currentPackage: %s", currentPackage)); - } - if (currentClass != null) { - logd(String.format("currentClass: %s", currentClass.toSignatureString())); - } - if (currentMethod != null) { - logd(String.format("currentMethod: %s", currentMethod.toSignatureString())); - } - } - - return null; - } - } + public Stream<JDiffClassDescription> parseAsStream(VirtualPath path) { + ApiParser parser = getApiParser(path); - private void logd(String msg) { - Log.d(tag, msg); + return parser.parseAsStream(path); } } diff --git a/tests/signature/lib/android/src/android/signature/cts/ApiParser.java b/tests/signature/lib/android/src/android/signature/cts/ApiParser.java new file mode 100644 index 00000000000..15444ccada9 --- /dev/null +++ b/tests/signature/lib/android/src/android/signature/cts/ApiParser.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.signature.cts; + +import java.util.stream.Stream; + +/** + * Base class for parsers of API specification. + */ +abstract class ApiParser { + + /** + * Parse the contents of the path and generate a stream of {@link JDiffClassDescription} + * instances. + * + * @param path the path to the API specification. + * @return the stream of {@link JDiffClassDescription} instances. + */ + abstract Stream<JDiffClassDescription> parseAsStream(VirtualPath path); +} diff --git a/tests/signature/lib/android/src/android/signature/cts/CurrentApi.java b/tests/signature/lib/android/src/android/signature/cts/CurrentApi.java index 611bcb58c1c..c5e0d166afd 100644 --- a/tests/signature/lib/android/src/android/signature/cts/CurrentApi.java +++ b/tests/signature/lib/android/src/android/signature/cts/CurrentApi.java @@ -15,14 +15,6 @@ */ package android.signature.cts; -import android.signature.cts.JDiffClassDescription.JDiffConstructor; -import android.signature.cts.JDiffClassDescription.JDiffField; -import android.signature.cts.JDiffClassDescription.JDiffMethod; - -import java.lang.reflect.Modifier; - -import org.xmlpull.v1.XmlPullParser; - /** * Helper methods and constants used for parsing the current api file. */ @@ -32,159 +24,4 @@ public class CurrentApi { public static final String API_FILE_DIRECTORY = "/data/local/tmp/signature-test"; - public static final String CURRENT_API_FILE = - API_FILE_DIRECTORY + "/current.api"; - public static final String SYSTEM_CURRENT_API_FILE = - API_FILE_DIRECTORY + "/system-current.api"; - public static final String SYSTEM_REMOVED_API_FILE = - API_FILE_DIRECTORY + "/system-removed.api"; - - static final String TAG_ROOT = "api"; - static final String TAG_PACKAGE = "package"; - static final String TAG_CLASS = "class"; - static final String TAG_INTERFACE = "interface"; - static final String TAG_IMPLEMENTS = "implements"; - static final String TAG_CONSTRUCTOR = "constructor"; - static final String TAG_METHOD = "method"; - static final String TAG_PARAM = "parameter"; - static final String TAG_EXCEPTION = "exception"; - static final String TAG_FIELD = "field"; - - private static final String MODIFIER_ABSTRACT = "abstract"; - private static final String MODIFIER_FINAL = "final"; - private static final String MODIFIER_NATIVE = "native"; - private static final String MODIFIER_PRIVATE = "private"; - private static final String MODIFIER_PROTECTED = "protected"; - private static final String MODIFIER_PUBLIC = "public"; - private static final String MODIFIER_STATIC = "static"; - private static final String MODIFIER_SYNCHRONIZED = "synchronized"; - private static final String MODIFIER_TRANSIENT = "transient"; - private static final String MODIFIER_VOLATILE = "volatile"; - private static final String MODIFIER_VISIBILITY = "visibility"; - - static final String ATTRIBUTE_NAME = "name"; - private static final String ATTRIBUTE_VALUE = "value"; - private static final String ATTRIBUTE_EXTENDS = "extends"; - static final String ATTRIBUTE_TYPE = "type"; - private static final String ATTRIBUTE_RETURN = "return"; - - /** - * Load field information from xml to memory. - * - * @param className of the class being examined which will be shown in error messages - * @param parser The XmlPullParser which carries the xml information. - * @return the new field - */ - static JDiffField loadFieldInfo(String className, XmlPullParser parser) { - String fieldName = parser.getAttributeValue(null, ATTRIBUTE_NAME); - String fieldType = parser.getAttributeValue(null, ATTRIBUTE_TYPE); - int modifier = jdiffModifierToReflectionFormat(className, parser); - String value = parser.getAttributeValue(null, ATTRIBUTE_VALUE); - return new JDiffField(fieldName, fieldType, modifier, value); - } - - /** - * Load method information from xml to memory. - * - * @param className of the class being examined which will be shown in error messages - * @param parser The XmlPullParser which carries the xml information. - * @return the newly loaded method. - */ - static JDiffMethod loadMethodInfo(String className, XmlPullParser parser) { - String methodName = parser.getAttributeValue(null, ATTRIBUTE_NAME); - String returnType = parser.getAttributeValue(null, ATTRIBUTE_RETURN); - int modifier = jdiffModifierToReflectionFormat(className, parser); - return new JDiffMethod(methodName, modifier, returnType); - } - - /** - * Load constructor information from xml to memory. - * - * @param parser The XmlPullParser which carries the xml information. - * @param currentClass the current class being loaded. - * @return the new constructor - */ - static JDiffConstructor loadConstructorInfo( - XmlPullParser parser, JDiffClassDescription currentClass) { - String name = currentClass.getClassName(); - int modifier = jdiffModifierToReflectionFormat(name, parser); - return new JDiffConstructor(name, modifier); - } - - /** - * Load class or interface information to memory. - * - * @param parser The XmlPullParser which carries the xml information. - * @param isInterface true if the current class is an interface, otherwise is false. - * @param pkg the name of the java package this class can be found in. - * @return the new class description. - */ - static JDiffClassDescription loadClassInfo( - XmlPullParser parser, boolean isInterface, String pkg) { - String className = parser.getAttributeValue(null, ATTRIBUTE_NAME); - JDiffClassDescription currentClass = new JDiffClassDescription(pkg, className); - - currentClass.setModifier(jdiffModifierToReflectionFormat(className, parser)); - currentClass.setType(isInterface ? JDiffClassDescription.JDiffType.INTERFACE : - JDiffClassDescription.JDiffType.CLASS); - currentClass.setExtendsClass(parser.getAttributeValue(null, ATTRIBUTE_EXTENDS)); - return currentClass; - } - - /** - * Convert string modifier to int modifier. - * - * @param name of the class/method/field being examined which will be shown in error messages - * @param key modifier name - * @param value modifier value - * @return converted modifier value - */ - private static int modifierDescriptionToReflectedType(String name, String key, String value) { - if (key.equals(MODIFIER_ABSTRACT)) { - return value.equals("true") ? Modifier.ABSTRACT : 0; - } else if (key.equals(MODIFIER_FINAL)) { - return value.equals("true") ? Modifier.FINAL : 0; - } else if (key.equals(MODIFIER_NATIVE)) { - return value.equals("true") ? Modifier.NATIVE : 0; - } else if (key.equals(MODIFIER_STATIC)) { - return value.equals("true") ? Modifier.STATIC : 0; - } else if (key.equals(MODIFIER_SYNCHRONIZED)) { - return value.equals("true") ? Modifier.SYNCHRONIZED : 0; - } else if (key.equals(MODIFIER_TRANSIENT)) { - return value.equals("true") ? Modifier.TRANSIENT : 0; - } else if (key.equals(MODIFIER_VOLATILE)) { - return value.equals("true") ? Modifier.VOLATILE : 0; - } else if (key.equals(MODIFIER_VISIBILITY)) { - if (value.equals(MODIFIER_PRIVATE)) { - throw new RuntimeException("Private visibility found in API spec: " + name); - } else if (value.equals(MODIFIER_PROTECTED)) { - return Modifier.PROTECTED; - } else if (value.equals(MODIFIER_PUBLIC)) { - return Modifier.PUBLIC; - } else if ("".equals(value)) { - // If the visibility is "", it means it has no modifier. - // which is package private. We should return 0 for this modifier. - return 0; - } else { - throw new RuntimeException("Unknown modifier found in API spec: " + value); - } - } - return 0; - } - - /** - * Transfer string modifier to int one. - * - * @param name of the class/method/field being examined which will be shown in error messages - * @param parser XML resource parser - * @return converted modifier - */ - private static int jdiffModifierToReflectionFormat(String name, XmlPullParser parser){ - int modifier = 0; - for (int i = 0;i < parser.getAttributeCount();i++) { - modifier |= modifierDescriptionToReflectedType(name, parser.getAttributeName(i), - parser.getAttributeValue(i)); - } - return modifier; - } } diff --git a/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java b/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java new file mode 100644 index 00000000000..8e5d0bb1721 --- /dev/null +++ b/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java @@ -0,0 +1,617 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT 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.signature.cts; + +import android.signature.cts.JDiffClassDescription.JDiffConstructor; +import android.signature.cts.JDiffClassDescription.JDiffField; +import android.signature.cts.JDiffClassDescription.JDiffMethod; +import android.util.Log; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.Spliterator; +import java.util.function.Consumer; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +/** + * Parser for the XML representation of an API specification. + */ +class XmlApiParser extends ApiParser { + + private static final String TAG_ROOT = "api"; + + private static final String TAG_PACKAGE = "package"; + + private static final String TAG_CLASS = "class"; + + private static final String TAG_INTERFACE = "interface"; + + private static final String TAG_IMPLEMENTS = "implements"; + + private static final String TAG_CONSTRUCTOR = "constructor"; + + private static final String TAG_METHOD = "method"; + + private static final String TAG_PARAM = "parameter"; + + private static final String TAG_EXCEPTION = "exception"; + + private static final String TAG_FIELD = "field"; + + private static final String ATTRIBUTE_NAME = "name"; + + private static final String ATTRIBUTE_TYPE = "type"; + + private static final String ATTRIBUTE_VALUE = "value"; + + private static final String ATTRIBUTE_EXTENDS = "extends"; + + private static final String ATTRIBUTE_RETURN = "return"; + + private static final String MODIFIER_ABSTRACT = "abstract"; + + private static final String MODIFIER_FINAL = "final"; + + private static final String MODIFIER_NATIVE = "native"; + + private static final String MODIFIER_PRIVATE = "private"; + + private static final String MODIFIER_PROTECTED = "protected"; + + private static final String MODIFIER_PUBLIC = "public"; + + private static final String MODIFIER_STATIC = "static"; + + private static final String MODIFIER_SYNCHRONIZED = "synchronized"; + + private static final String MODIFIER_TRANSIENT = "transient"; + + private static final String MODIFIER_VOLATILE = "volatile"; + + private static final String MODIFIER_VISIBILITY = "visibility"; + + private static final Set<String> KEY_TAG_SET; + + static { + KEY_TAG_SET = new HashSet<>(); + Collections.addAll(KEY_TAG_SET, + TAG_PACKAGE, + TAG_CLASS, + TAG_INTERFACE, + TAG_IMPLEMENTS, + TAG_CONSTRUCTOR, + TAG_METHOD, + TAG_PARAM, + TAG_EXCEPTION, + TAG_FIELD); + } + + private final String tag; + + private final XmlPullParserFactory factory; + + XmlApiParser(String tag) { + this.tag = tag; + try { + factory = XmlPullParserFactory.newInstance(); + } catch (XmlPullParserException e) { + throw new RuntimeException(e); + } + } + + /** + * Load field information from xml to memory. + * + * @param className + * of the class being examined which will be shown in error messages + * @param parser + * The XmlPullParser which carries the xml information. + * @return the new field + */ + private static JDiffField loadFieldInfo(String className, XmlPullParser parser) { + String fieldName = parser.getAttributeValue(null, ATTRIBUTE_NAME); + String fieldType = canonicalizeType(parser.getAttributeValue(null, ATTRIBUTE_TYPE)); + int modifier = jdiffModifierToReflectionFormat(className, parser); + String value = parser.getAttributeValue(null, ATTRIBUTE_VALUE); + + // Canonicalize the expected value to ensure that it is consistent with the values obtained + // using reflection by ApiComplianceChecker.getFieldValueAsString(...). + if (value != null) { + + // An unquoted null String value actually means null. It cannot be confused with a + // String containing the word null as that would be surrounded with double quotes. + if (value.equals("null")) { + value = null; + } else { + switch (fieldType) { + case "java.lang.String": + value = unescapeFieldStringValue(value); + break; + + case "char": + // A character is encoded in XML as its numeric value. Convert it to a + // string containing the single character. + char c = (char) Integer.parseInt(value); + value = String.valueOf(c); + break; + + case "double": + switch (value) { + case "(-1.0/0.0)": + value = "-Infinity"; + break; + case "(0.0/0.0)": + value = "NaN"; + break; + case "(1.0/0.0)": + value = "Infinity"; + break; + } + break; + + case "float": + switch (value) { + case "(-1.0f/0.0f)": + value = "-Infinity"; + break; + case "(0.0f/0.0f)": + value = "NaN"; + break; + case "(1.0f/0.0f)": + value = "Infinity"; + break; + default: + // Remove the trailing f. + if (value.endsWith("f")) { + value = value.substring(0, value.length() - 1); + } + } + break; + + case "long": + // Remove the trailing L. + if (value.endsWith("L")) { + value = value.substring(0, value.length() - 1); + } + break; + } + } + } + + return new JDiffField(fieldName, fieldType, modifier, value); + } + + /** + * Load method information from xml to memory. + * + * @param className + * of the class being examined which will be shown in error messages + * @param parser + * The XmlPullParser which carries the xml information. + * @return the newly loaded method. + */ + private static JDiffMethod loadMethodInfo(String className, XmlPullParser parser) { + String methodName = parser.getAttributeValue(null, ATTRIBUTE_NAME); + String returnType = parser.getAttributeValue(null, ATTRIBUTE_RETURN); + int modifier = jdiffModifierToReflectionFormat(className, parser); + return new JDiffMethod(methodName, modifier, canonicalizeType(returnType)); + } + + /** + * Load constructor information from xml to memory. + * + * @param parser + * The XmlPullParser which carries the xml information. + * @param currentClass + * the current class being loaded. + * @return the new constructor + */ + private static JDiffConstructor loadConstructorInfo( + XmlPullParser parser, JDiffClassDescription currentClass) { + String name = currentClass.getClassName(); + int modifier = jdiffModifierToReflectionFormat(name, parser); + return new JDiffConstructor(name, modifier); + } + + /** + * Load class or interface information to memory. + * + * @param parser + * The XmlPullParser which carries the xml information. + * @param isInterface + * true if the current class is an interface, otherwise is false. + * @param pkg + * the name of the java package this class can be found in. + * @return the new class description. + */ + private static JDiffClassDescription loadClassInfo( + XmlPullParser parser, boolean isInterface, String pkg) { + String className = parser.getAttributeValue(null, ATTRIBUTE_NAME); + JDiffClassDescription currentClass = new JDiffClassDescription(pkg, className); + + currentClass.setModifier(jdiffModifierToReflectionFormat(className, parser)); + currentClass.setType(isInterface ? JDiffClassDescription.JDiffType.INTERFACE : + JDiffClassDescription.JDiffType.CLASS); + currentClass.setExtendsClass(parser.getAttributeValue(null, ATTRIBUTE_EXTENDS)); + return currentClass; + } + + /** + * Transfer string modifier to int one. + * + * @param name + * of the class/method/field being examined which will be shown in error messages + * @param parser + * XML resource parser + * @return converted modifier + */ + private static int jdiffModifierToReflectionFormat(String name, XmlPullParser parser) { + int modifier = 0; + for (int i = 0; i < parser.getAttributeCount(); i++) { + modifier |= modifierDescriptionToReflectedType(name, parser.getAttributeName(i), + parser.getAttributeValue(i)); + } + return modifier; + } + + /** + * Convert string modifier to int modifier. + * + * @param name + * of the class/method/field being examined which will be shown in error messages + * @param key + * modifier name + * @param value + * modifier value + * @return converted modifier value + */ + private static int modifierDescriptionToReflectedType(String name, String key, String value) { + switch (key) { + case MODIFIER_ABSTRACT: + return value.equals("true") ? Modifier.ABSTRACT : 0; + case MODIFIER_FINAL: + return value.equals("true") ? Modifier.FINAL : 0; + case MODIFIER_NATIVE: + return value.equals("true") ? Modifier.NATIVE : 0; + case MODIFIER_STATIC: + return value.equals("true") ? Modifier.STATIC : 0; + case MODIFIER_SYNCHRONIZED: + return value.equals("true") ? Modifier.SYNCHRONIZED : 0; + case MODIFIER_TRANSIENT: + return value.equals("true") ? Modifier.TRANSIENT : 0; + case MODIFIER_VOLATILE: + return value.equals("true") ? Modifier.VOLATILE : 0; + case MODIFIER_VISIBILITY: + switch (value) { + case MODIFIER_PRIVATE: + throw new RuntimeException("Private visibility found in API spec: " + name); + case MODIFIER_PROTECTED: + return Modifier.PROTECTED; + case MODIFIER_PUBLIC: + return Modifier.PUBLIC; + case "": + // If the visibility is "", it means it has no modifier. + // which is package private. We should return 0 for this modifier. + return 0; + default: + throw new RuntimeException("Unknown modifier found in API spec: " + value); + } + } + return 0; + } + + @Override + public Stream<JDiffClassDescription> parseAsStream(VirtualPath path) { + XmlPullParser parser; + try { + parser = factory.newPullParser(); + parser.setInput(path.newInputStream(), null); + return StreamSupport + .stream(new ClassDescriptionSpliterator(parser), false); + } catch (XmlPullParserException | IOException e) { + throw new RuntimeException("Could not parse " + path, e); + } + } + + private class ClassDescriptionSpliterator implements Spliterator<JDiffClassDescription> { + + private final XmlPullParser parser; + + JDiffClassDescription currentClass = null; + + String currentPackage = ""; + + JDiffMethod currentMethod = null; + + ClassDescriptionSpliterator(XmlPullParser parser) + throws IOException, XmlPullParserException { + this.parser = parser; + logd(String.format("Name: %s", parser.getName())); + logd(String.format("Text: %s", parser.getText())); + logd(String.format("Namespace: %s", parser.getNamespace())); + logd(String.format("Line Number: %s", parser.getLineNumber())); + logd(String.format("Column Number: %s", parser.getColumnNumber())); + logd(String.format("Position Description: %s", parser.getPositionDescription())); + beginDocument(parser); + } + + @Override + public boolean tryAdvance(Consumer<? super JDiffClassDescription> action) { + JDiffClassDescription classDescription; + try { + classDescription = next(); + } catch (IOException | XmlPullParserException e) { + throw new RuntimeException(e); + } + + if (classDescription == null) { + return false; + } + action.accept(classDescription); + return true; + } + + @Override + public Spliterator<JDiffClassDescription> trySplit() { + return null; + } + + @Override + public long estimateSize() { + return Long.MAX_VALUE; + } + + @Override + public int characteristics() { + return ORDERED | DISTINCT | NONNULL | IMMUTABLE; + } + + private void beginDocument(XmlPullParser parser) + throws XmlPullParserException, IOException { + int type; + do { + type = parser.next(); + } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT); + + if (type != XmlPullParser.START_TAG) { + throw new XmlPullParserException("No start tag found"); + } + + if (!parser.getName().equals(TAG_ROOT)) { + throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() + + ", expected " + TAG_ROOT); + } + } + + private JDiffClassDescription next() throws IOException, XmlPullParserException { + int type; + while (true) { + do { + type = parser.next(); + } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT + && type != XmlPullParser.END_TAG); + + if (type == XmlPullParser.END_DOCUMENT) { + logd("Reached end of document"); + break; + } + + String tagname = parser.getName(); + if (type == XmlPullParser.END_TAG) { + if (TAG_CLASS.equals(tagname) || TAG_INTERFACE.equals(tagname)) { + logd("Reached end of class: " + currentClass); + return currentClass; + } else if (TAG_PACKAGE.equals(tagname)) { + currentPackage = ""; + } + continue; + } + + if (!KEY_TAG_SET.contains(tagname)) { + continue; + } + + switch (tagname) { + case TAG_PACKAGE: + currentPackage = parser.getAttributeValue(null, ATTRIBUTE_NAME); + break; + + case TAG_CLASS: + currentClass = loadClassInfo(parser, false, currentPackage); + break; + + case TAG_INTERFACE: + currentClass = loadClassInfo(parser, true, currentPackage); + break; + + case TAG_IMPLEMENTS: + currentClass + .addImplInterface(parser.getAttributeValue(null, ATTRIBUTE_NAME)); + break; + + case TAG_CONSTRUCTOR: + JDiffConstructor constructor = + loadConstructorInfo(parser, currentClass); + currentClass.addConstructor(constructor); + currentMethod = constructor; + break; + + case TAG_METHOD: + currentMethod = loadMethodInfo(currentClass.getClassName(), parser); + currentClass.addMethod(currentMethod); + break; + + case TAG_PARAM: + String paramType = parser.getAttributeValue(null, ATTRIBUTE_TYPE); + currentMethod.addParam(canonicalizeType(paramType)); + break; + + case TAG_EXCEPTION: + currentMethod.addException(parser.getAttributeValue(null, ATTRIBUTE_TYPE)); + break; + + case TAG_FIELD: + JDiffField field = loadFieldInfo(currentClass.getClassName(), parser); + currentClass.addField(field); + break; + + default: + throw new RuntimeException("unknown tag exception:" + tagname); + } + + if (currentPackage != null) { + logd(String.format("currentPackage: %s", currentPackage)); + } + if (currentClass != null) { + logd(String.format("currentClass: %s", currentClass.toSignatureString())); + } + if (currentMethod != null) { + logd(String.format("currentMethod: %s", currentMethod.toSignatureString())); + } + } + + return null; + } + } + + private void logd(String msg) { + Log.d(tag, msg); + } + + // This unescapes the string format used by doclava and so needs to be kept in sync with any + // changes made to that format. + private static String unescapeFieldStringValue(String str) { + // Skip over leading and trailing ". + int start = 0; + if (str.charAt(start) == '"') { + ++start; + } + int end = str.length(); + if (str.charAt(end - 1) == '"') { + --end; + } + + // If there's no special encoding strings in the string then just return it without the + // leading and trailing "s. + if (str.indexOf('\\') == -1) { + return str.substring(start, end); + } + + final StringBuilder buf = new StringBuilder(str.length()); + char escaped = 0; + final int START = 0; + final int CHAR1 = 1; + final int CHAR2 = 2; + final int CHAR3 = 3; + final int CHAR4 = 4; + final int ESCAPE = 5; + int state = START; + + for (int i = start; i < end; i++) { + final char c = str.charAt(i); + switch (state) { + case START: + if (c == '\\') { + state = ESCAPE; + } else { + buf.append(c); + } + break; + case ESCAPE: + switch (c) { + case '\\': + buf.append('\\'); + state = START; + break; + case 't': + buf.append('\t'); + state = START; + break; + case 'b': + buf.append('\b'); + state = START; + break; + case 'r': + buf.append('\r'); + state = START; + break; + case 'n': + buf.append('\n'); + state = START; + break; + case 'f': + buf.append('\f'); + state = START; + break; + case '\'': + buf.append('\''); + state = START; + break; + case '\"': + buf.append('\"'); + state = START; + break; + case 'u': + state = CHAR1; + escaped = 0; + break; + } + break; + case CHAR1: + case CHAR2: + case CHAR3: + case CHAR4: + escaped <<= 4; + if (c >= '0' && c <= '9') { + escaped |= c - '0'; + } else if (c >= 'a' && c <= 'f') { + escaped |= 10 + (c - 'a'); + } else if (c >= 'A' && c <= 'F') { + escaped |= 10 + (c - 'A'); + } else { + throw new RuntimeException( + "bad escape sequence: '" + c + "' at pos " + i + " in: \"" + + str + "\""); + } + if (state == CHAR4) { + buf.append(escaped); + state = START; + } else { + state++; + } + break; + } + } + if (state != START) { + throw new RuntimeException("unfinished escape sequence: " + str); + } + return buf.toString(); + } + + /** + * Canonicalize a possibly generic type. + */ + private static String canonicalizeType(String type) { + // Remove trailing spaces after commas. + return type.replace(", ", ","); + } +} diff --git a/tests/signature/lib/common/src/android/signature/cts/AbstractApiChecker.java b/tests/signature/lib/common/src/android/signature/cts/AbstractApiChecker.java index 75632ac8e63..03c4a85e417 100644 --- a/tests/signature/lib/common/src/android/signature/cts/AbstractApiChecker.java +++ b/tests/signature/lib/common/src/android/signature/cts/AbstractApiChecker.java @@ -19,7 +19,9 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; +import java.util.stream.Collectors; /** * Base class for those that process a set of API definition files and perform some checking on @@ -187,14 +189,22 @@ public abstract class AbstractApiChecker { */ private void checkConstructorCompliance(JDiffClassDescription classDescription, Class<?> runtimeClass) { + Map<Constructor, String> mismatchReasons = new LinkedHashMap<>(); for (JDiffClassDescription.JDiffConstructor con : classDescription.getConstructors()) { try { - Constructor<?> c = ReflectionHelper.findMatchingConstructor(runtimeClass, con); + Constructor<?> c = ReflectionHelper.findMatchingConstructor(runtimeClass, con, + mismatchReasons); if (c == null) { resultObserver.notifyFailure(FailureType.MISSING_CONSTRUCTOR, con.toReadableString(classDescription.getAbsoluteClassName()), - "No constructor with correct signature found:" + - con.toSignatureString()); + String.format( + "No constructor with correct signature found. The following" + + " constructors were rejected:\n%s", + mismatchReasons.entrySet() + .stream() + .map(e -> String.format("\t\t%s - %s\n", + e.getKey(), e.getValue())) + .collect(Collectors.joining()))); } else { checkConstructor(classDescription, runtimeClass, con, c); } @@ -220,18 +230,27 @@ public abstract class AbstractApiChecker { */ private void checkMethodCompliance(JDiffClassDescription classDescription, Class<?> runtimeClass) { + Map<Method, String> mismatchReasons = new LinkedHashMap<>(); for (JDiffClassDescription.JDiffMethod method : classDescription.getMethods()) { try { - - Method m = ReflectionHelper.findMatchingMethod(runtimeClass, method); + Method m = ReflectionHelper.findMatchingMethod( + runtimeClass, method, mismatchReasons); if (m == null) { resultObserver.notifyFailure(FailureType.MISSING_METHOD, method.toReadableString(classDescription.getAbsoluteClassName()), - "No method with correct signature found, looking for:" + - method.toSignatureString()); + String.format( + "No method with correct signature found. The following methods" + + " with the same name were rejected:\n%s", + mismatchReasons.entrySet() + .stream() + .map(e -> String.format("\t\t%s - %s\n", + e.getKey(), e.getValue())) + .collect(Collectors.joining()))); } else { checkMethod(classDescription, runtimeClass, method, m); } + // Clear the list. + mismatchReasons.clear(); } catch (Exception e) { LogHelper.loge("Got exception when checking method compliance", e); resultObserver.notifyFailure(FailureType.CAUGHT_EXCEPTION, diff --git a/tests/signature/lib/common/src/android/signature/cts/ApiComplianceChecker.java b/tests/signature/lib/common/src/android/signature/cts/ApiComplianceChecker.java index b3466489dc8..df7c18b4d4d 100644 --- a/tests/signature/lib/common/src/android/signature/cts/ApiComplianceChecker.java +++ b/tests/signature/lib/common/src/android/signature/cts/ApiComplianceChecker.java @@ -15,11 +15,13 @@ */ package android.signature.cts; +import android.signature.cts.JDiffClassDescription.JDiffField; +import android.signature.cts.ReflectionHelper.DefaultTypeComparator; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.lang.reflect.Type; +import java.util.Formatter; import java.util.HashSet; import java.util.Objects; import java.util.Set; @@ -99,14 +101,16 @@ public class ApiComplianceChecker extends AbstractApiChecker { // check father class if (!checkClassExtendsCompliance(classDescription, runtimeClass)) { resultObserver.notifyFailure(FailureType.mismatch(classDescription), - classDescription.getAbsoluteClassName(), "Extends mismatch"); + classDescription.getAbsoluteClassName(), + "Extends mismatch, expected " + classDescription.getExtendedClass()); return false; } // check implements interface if (!checkClassImplementsCompliance(classDescription, runtimeClass)) { resultObserver.notifyFailure(FailureType.mismatch(classDescription), - classDescription.getAbsoluteClassName(), "Implements mismatch"); + classDescription.getAbsoluteClassName(), + "Implements mismatch, expected " + classDescription.getImplInterfaces()); return false; } } @@ -162,7 +166,7 @@ public class ApiComplianceChecker extends AbstractApiChecker { return null; } else { return String.format("modifier mismatch - description (%s), class (%s)", - Modifier.toString(apiModifiers), Modifier.toString(reflectionModifiers)); + getModifierString(apiModifiers), getModifierString(reflectionModifiers)); } } @@ -254,111 +258,160 @@ public class ApiComplianceChecker extends AbstractApiChecker { @Override protected void checkField(JDiffClassDescription classDescription, Class<?> runtimeClass, - JDiffClassDescription.JDiffField fieldDescription, Field field) { - if (field.getModifiers() != fieldDescription.mModifier) { + JDiffField fieldDescription, Field field) { + int expectedModifiers = fieldDescription.mModifier; + int actualModifiers = field.getModifiers(); + if (actualModifiers != expectedModifiers) { resultObserver.notifyFailure(FailureType.MISMATCH_FIELD, fieldDescription.toReadableString(classDescription.getAbsoluteClassName()), - "Non-compatible field modifiers found when looking for " + - fieldDescription.toSignatureString()); - } else if (!checkFieldValueCompliance(fieldDescription, field)) { + String.format( + "Incompatible field modifiers, expected %s, found %s", + getModifierString(expectedModifiers), + getModifierString(actualModifiers))); + } + + String expectedFieldType = fieldDescription.mFieldType; + String actualFieldType = ReflectionHelper.typeToString(field.getGenericType()); + if (!DefaultTypeComparator.INSTANCE.compare(expectedFieldType, actualFieldType)) { + resultObserver.notifyFailure( + FailureType.MISMATCH_FIELD, + fieldDescription.toReadableString(classDescription.getAbsoluteClassName()), + String.format("Incompatible field type found, expected %s, found %s", + expectedFieldType, actualFieldType)); + } + + String message = checkFieldValueCompliance(fieldDescription, field); + if (message != null) { resultObserver.notifyFailure(FailureType.MISMATCH_FIELD, fieldDescription.toReadableString(classDescription.getAbsoluteClassName()), - "Incorrect field value found when looking for " + - fieldDescription.toSignatureString()); - } else if (!field.getType().getCanonicalName().equals(fieldDescription.mFieldType)) { - // type name does not match, but this might be a generic - String genericTypeName = null; - Type type = field.getGenericType(); - if (type != null) { - genericTypeName = type instanceof Class ? ((Class<?>) type).getName() : - type.toString().replace('$', '.'); - } - if (genericTypeName == null || !genericTypeName.equals(fieldDescription.mFieldType)) { - resultObserver.notifyFailure( - FailureType.MISMATCH_FIELD, - fieldDescription.toReadableString(classDescription.getAbsoluteClassName()), - "Non-compatible field type found when looking for " + - fieldDescription.toSignatureString()); - } + message); } } + private static final int BRIDGE = 0x00000040; + private static final int VARARGS = 0x00000080; + private static final int SYNTHETIC = 0x00001000; + private static final int ANNOTATION = 0x00002000; + private static final int ENUM = 0x00004000; + private static final int MANDATED = 0x00008000; + + private static String getModifierString(int modifiers) { + Formatter formatter = new Formatter(); + String m = Modifier.toString(modifiers); + formatter.format("<%s", m); + String sep = m.isEmpty() ? "" : " "; + if ((modifiers & BRIDGE) != 0) { + formatter.format("%senum", sep); + sep = " "; + } + if ((modifiers & VARARGS) != 0) { + formatter.format("%svarargs", sep); + sep = " "; + } + if ((modifiers & SYNTHETIC) != 0) { + formatter.format("%ssynthetic", sep); + sep = " "; + } + if ((modifiers & ANNOTATION) != 0) { + formatter.format("%sannotation", sep); + sep = " "; + } + if ((modifiers & ENUM) != 0) { + formatter.format("%senum", sep); + sep = " "; + } + if ((modifiers & MANDATED) != 0) { + formatter.format("%smandated", sep); + } + return formatter.format("> (0x%x)", modifiers).toString(); + } + /** * Checks whether the field values are compatible. * * @param apiField The field as defined by the platform API. * @param deviceField The field as defined by the device under test. */ - private static boolean checkFieldValueCompliance(JDiffClassDescription.JDiffField apiField, Field deviceField) { + private static String checkFieldValueCompliance(JDiffField apiField, Field deviceField) { if ((apiField.mModifier & Modifier.FINAL) == 0 || (apiField.mModifier & Modifier.STATIC) == 0) { // Only final static fields can have fixed values. - return true; + return null; } - if (apiField.getValueString() == null) { + String apiFieldValue = apiField.getValueString(); + if (apiFieldValue == null) { // If we don't define a constant value for it, then it can be anything. - return true; + return null; + } + + // Convert char into a number to match the value returned from device field. The device + // field does not + if (deviceField.getType() == char.class) { + apiFieldValue = convertCharToCanonicalValue(apiFieldValue.charAt(0)); } + + String deviceFieldValue = getFieldValueAsString(deviceField); + if (!Objects.equals(apiFieldValue, deviceFieldValue)) { + return String.format("Incorrect field value, expected <%s>, found <%s>", + apiFieldValue, deviceFieldValue); + + } + + return null; + } + + private static String getFieldValueAsString(Field deviceField) { // Some fields may be protected or package-private deviceField.setAccessible(true); try { - switch (apiField.mFieldType) { - case "byte": - return Objects.equals(apiField.getValueString(), - Byte.toString(deviceField.getByte(null))); - case "char": - return Objects.equals(apiField.getValueString(), - Integer.toString(deviceField.getChar(null))); - case "short": - return Objects.equals(apiField.getValueString(), - Short.toString(deviceField.getShort(null))); - case "int": - return Objects.equals(apiField.getValueString(), - Integer.toString(deviceField.getInt(null))); - case "long": - return Objects.equals(apiField.getValueString(), - Long.toString(deviceField.getLong(null)) + "L"); - case "float": - return Objects.equals(apiField.getValueString(), - canonicalizeFloatingPoint( - Float.toString(deviceField.getFloat(null)), "f")); - case "double": - return Objects.equals(apiField.getValueString(), - canonicalizeFloatingPoint( - Double.toString(deviceField.getDouble(null)), "")); - case "boolean": - return Objects.equals(apiField.getValueString(), - Boolean.toString(deviceField.getBoolean(null))); - case "java.lang.String": - String value = apiField.getValueString(); - // Remove the quotes the value string is wrapped in - value = unescapeFieldStringValue(value.substring(1, value.length() - 1)); - return Objects.equals(value, deviceField.get(null)); - default: - return true; + Class<?> fieldType = deviceField.getType(); + if (fieldType == byte.class) { + return Byte.toString(deviceField.getByte(null)); + } else if (fieldType == char.class) { + return convertCharToCanonicalValue(deviceField.getChar(null)); + } else if (fieldType == short.class) { + return Short.toString(deviceField.getShort(null)); + } else if (fieldType == int.class) { + return Integer.toString(deviceField.getInt(null)); + } else if (fieldType == long.class) { + return Long.toString(deviceField.getLong(null)); + } else if (fieldType == float.class) { + return canonicalizeFloatingPoint( + Float.toString(deviceField.getFloat(null))); + } else if (fieldType == double.class) { + return canonicalizeFloatingPoint( + Double.toString(deviceField.getDouble(null))); + } else if (fieldType == boolean.class) { + return Boolean.toString(deviceField.getBoolean(null)); + } else if (fieldType == java.lang.String.class) { + return (String) deviceField.get(null); + } else { + return null; } } catch (IllegalAccessException e) { throw new RuntimeException(e); } } + private static String convertCharToCanonicalValue(char c) { + return String.format("'%c' (0x%x)", c, (int) c); + } + /** * Canonicalize the string representation of floating point numbers. * * This needs to be kept in sync with the doclava canonicalization. */ - private static String canonicalizeFloatingPoint(String val, String suffix) { + private static String canonicalizeFloatingPoint(String val) { switch (val) { case "Infinity": - return "(1.0" + suffix + "/0.0" + suffix + ")"; case "-Infinity": - return "(-1.0" + suffix + "/0.0" + suffix + ")"; case "NaN": - return "(0.0" + suffix + "/0.0" + suffix + ")"; + return val; } if (val.indexOf('E') != -1) { - return val + suffix; + return val; } // 1.0 is the only case where a trailing "0" is allowed. @@ -368,108 +421,7 @@ public class ApiComplianceChecker extends AbstractApiChecker { while (i >= d + 2 && val.charAt(i) == '0') { val = val.substring(0, i--); } - return val + suffix; - } - - // This unescapes the string format used by doclava and so needs to be kept in sync with any - // changes made to that format. - private static String unescapeFieldStringValue(String str) { - final int N = str.length(); - - // If there's no special encoding strings in the string then just return it. - if (str.indexOf('\\') == -1) { - return str; - } - - final StringBuilder buf = new StringBuilder(str.length()); - char escaped = 0; - final int START = 0; - final int CHAR1 = 1; - final int CHAR2 = 2; - final int CHAR3 = 3; - final int CHAR4 = 4; - final int ESCAPE = 5; - int state = START; - - for (int i = 0; i < N; i++) { - final char c = str.charAt(i); - switch (state) { - case START: - if (c == '\\') { - state = ESCAPE; - } else { - buf.append(c); - } - break; - case ESCAPE: - switch (c) { - case '\\': - buf.append('\\'); - state = START; - break; - case 't': - buf.append('\t'); - state = START; - break; - case 'b': - buf.append('\b'); - state = START; - break; - case 'r': - buf.append('\r'); - state = START; - break; - case 'n': - buf.append('\n'); - state = START; - break; - case 'f': - buf.append('\f'); - state = START; - break; - case '\'': - buf.append('\''); - state = START; - break; - case '\"': - buf.append('\"'); - state = START; - break; - case 'u': - state = CHAR1; - escaped = 0; - break; - } - break; - case CHAR1: - case CHAR2: - case CHAR3: - case CHAR4: - escaped <<= 4; - if (c >= '0' && c <= '9') { - escaped |= c - '0'; - } else if (c >= 'a' && c <= 'f') { - escaped |= 10 + (c - 'a'); - } else if (c >= 'A' && c <= 'F') { - escaped |= 10 + (c - 'A'); - } else { - throw new RuntimeException( - "bad escape sequence: '" + c + "' at pos " + i + " in: \"" - + str + "\""); - } - if (state == CHAR4) { - buf.append(escaped); - state = START; - } else { - state++; - } - break; - } - } - if (state != START) { - throw new RuntimeException("unfinished escape sequence: " + str); - } - return buf.toString(); + return val; } @Override @@ -553,7 +505,7 @@ public class ApiComplianceChecker extends AbstractApiChecker { return null; } else { return String.format("modifier mismatch - description (%s), method (%s), for %s", - Modifier.toString(apiModifiers), Modifier.toString(reflectionModifiers), genericString); + getModifierString(apiModifiers), getModifierString(reflectionModifiers), genericString); } } diff --git a/tests/signature/lib/common/src/android/signature/cts/InterfaceChecker.java b/tests/signature/lib/common/src/android/signature/cts/InterfaceChecker.java index 6be5f96ccd0..66492ffe13a 100644 --- a/tests/signature/lib/common/src/android/signature/cts/InterfaceChecker.java +++ b/tests/signature/lib/common/src/android/signature/cts/InterfaceChecker.java @@ -20,6 +20,7 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Comparator; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -112,8 +113,9 @@ class InterfaceChecker { } private boolean findMethod(JDiffClassDescription classDescription, Method method) { + Map<Method, String> matchNameNotSignature = new LinkedHashMap<>(); for (JDiffClassDescription.JDiffMethod jdiffMethod : classDescription.getMethods()) { - if (ReflectionHelper.matches(jdiffMethod, method)) { + if (ReflectionHelper.matchesSignature(jdiffMethod, method, matchNameNotSignature)) { return true; } } diff --git a/tests/signature/lib/common/src/android/signature/cts/JDiffClassDescription.java b/tests/signature/lib/common/src/android/signature/cts/JDiffClassDescription.java index 30584c95912..97f11d0b8e2 100644 --- a/tests/signature/lib/common/src/android/signature/cts/JDiffClassDescription.java +++ b/tests/signature/lib/common/src/android/signature/cts/JDiffClassDescription.java @@ -325,9 +325,9 @@ public class JDiffClassDescription { StringBuilder sb = new StringBuilder(); // access level - String accesLevel = convertModifiersToAccessLevel(mModifier); - if (!"".equals(accesLevel)) { - sb.append(accesLevel).append(" "); + String accessLevel = convertModifiersToAccessLevel(mModifier); + if (!"".equals(accessLevel)) { + sb.append(accessLevel).append(" "); } String modifierString = convertModifersToModifierString(mModifier); diff --git a/tests/signature/lib/common/src/android/signature/cts/ReflectionHelper.java b/tests/signature/lib/common/src/android/signature/cts/ReflectionHelper.java index 992b3fa6995..6b6140a073d 100644 --- a/tests/signature/lib/common/src/android/signature/cts/ReflectionHelper.java +++ b/tests/signature/lib/common/src/android/signature/cts/ReflectionHelper.java @@ -15,6 +15,8 @@ */ package android.signature.cts; +import android.signature.cts.JDiffClassDescription.JDiffConstructor; +import android.signature.cts.JDiffClassDescription.JDiffMethod; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -29,6 +31,7 @@ import java.lang.reflect.WildcardType; import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -123,10 +126,12 @@ public class ReflectionHelper { * * @param runtimeClass the class in which to search. * @param jdiffDes constructor description to find. + * @param mismatchReasons a map from rejected constructor to the reason it was rejected. * @return reflected constructor, or null if not found. */ static Constructor<?> findMatchingConstructor(Class<?> runtimeClass, - JDiffClassDescription.JDiffConstructor jdiffDes) { + JDiffConstructor jdiffDes, Map<Constructor, String> mismatchReasons) { + for (Constructor<?> c : runtimeClass.getDeclaredConstructors()) { Type[] params = c.getGenericParameterTypes(); boolean isStaticClass = ((runtimeClass.getModifiers() & Modifier.STATIC) != 0); @@ -148,8 +153,15 @@ public class ReflectionHelper { int i = 0; int j = startParamOffset; while (i < jdiffParamList.size()) { - if (!compareParam(jdiffParamList.get(i), params[j], + String expectedParameter = jdiffParamList.get(i); + Type actualParameter = params[j]; + if (!compareParam(expectedParameter, actualParameter, DefaultTypeComparator.INSTANCE)) { + mismatchReasons.put(c, + String.format("parameter %d mismatch: expected (%s), found (%s)", + i, + expectedParameter, + actualParameter)); isFound = false; break; } @@ -159,6 +171,11 @@ public class ReflectionHelper { if (isFound) { return c; } + } else { + mismatchReasons.put(c, + String.format("parameter list length mismatch: expected %d, found %d", + jdiffParamList.size(), + params.length)); } } return null; @@ -204,25 +221,33 @@ public class ReflectionHelper { * * @param runtimeClass the class in which to search. * @param method description of the method to find + * @param mismatchReasons a map from rejected method to the reason it was rejected, only + * contains methods with the same name. * @return the reflected method, or null if not found. */ - static Method findMatchingMethod(Class<?> runtimeClass, - JDiffClassDescription.JDiffMethod method) { + static Method findMatchingMethod( + Class<?> runtimeClass, JDiffMethod method, Map<Method, String> mismatchReasons) { // Search through the class to find the methods just in case the method was actually // declared in a superclass which is not part of the API and so was made to appear as if // it was declared in each of the hidden class' subclasses. Cannot use getMethods() as that // will only return public methods and the API includes protected methods. - while (runtimeClass != null) { - Method[] methods = runtimeClass.getDeclaredMethods(); + Class<?> currentClass = runtimeClass; + while (currentClass != null) { + Method[] reflectedMethods = currentClass.getDeclaredMethods(); + + for (Method reflectedMethod : reflectedMethods) { + // If the method names aren't equal, the methods can't match. + if (!method.mName.equals(reflectedMethod.getName())) { + continue; + } - for (Method m : methods) { - if (matches(method, m)) { - return m; + if (matchesSignature(method, reflectedMethod, mismatchReasons)) { + return reflectedMethod; } } - runtimeClass = runtimeClass.getSuperclass(); + currentClass = currentClass.getSuperclass(); } return null; @@ -233,15 +258,12 @@ public class ReflectionHelper { * * @param jDiffMethod the jDiffMethod to compare * @param reflectedMethod the reflected method to compare + * @param mismatchReasons map from method to reason it did not match, used when reporting + * missing methods. * @return true, if both methods are the same */ - static boolean matches(JDiffClassDescription.JDiffMethod jDiffMethod, - Method reflectedMethod) { - // If the method names aren't equal, the methods can't match. - if (!jDiffMethod.mName.equals(reflectedMethod.getName())) { - return false; - } - + static boolean matchesSignature(JDiffMethod jDiffMethod, Method reflectedMethod, + Map<Method, String> mismatchReasons) { // If the method is a bridge then use a special comparator for comparing types as // bridge methods created for generic methods may not have generic signatures. // See b/123558763 for more information. @@ -250,19 +272,26 @@ public class ReflectionHelper { String jdiffReturnType = jDiffMethod.mReturnType; String reflectionReturnType = typeToString(reflectedMethod.getGenericReturnType()); - List<String> jdiffParamList = jDiffMethod.mParamList; // Next, compare the return types of the two methods. If // they aren't equal, the methods can't match. if (!typeComparator.compare(jdiffReturnType, reflectionReturnType)) { + mismatchReasons.put(reflectedMethod, + String.format("return type mismatch: expected %s, found %s", jdiffReturnType, + reflectionReturnType)); return false; } + List<String> jdiffParamList = jDiffMethod.mParamList; Type[] params = reflectedMethod.getGenericParameterTypes(); // Next, check the method parameters. If they have different // parameter lengths, the two methods can't match. if (jdiffParamList.size() != params.length) { + mismatchReasons.put(reflectedMethod, + String.format("parameter list length mismatch: expected %s, found %s", + jdiffParamList.size(), + params.length)); return false; } @@ -290,15 +319,25 @@ public class ReflectionHelper { StringBuilder reflectedMethodParams = new StringBuilder(""); StringBuilder jdiffMethodParams = new StringBuilder(""); + String sep = ""; for (int i = 0; i < jdiffParamList.size(); i++) { - jdiffMethodParams.append(jdiffParamList.get(i)); - reflectedMethodParams.append(params[i]); + jdiffMethodParams.append(sep).append(jdiffParamList.get(i)); + reflectedMethodParams.append(sep).append(params[i].getTypeName()); + sep = ", "; } String jDiffFName = jdiffMethodParams.toString(); String refName = reflectedMethodParams.toString(); - return jDiffFName.equals(refName); + boolean signatureMatches = jDiffFName.equals(refName); + if (!signatureMatches) { + mismatchReasons.put(reflectedMethod, + String.format("parameter signature mismatch: expected (%s), found (%s)", + jDiffFName, + refName)); + } + + return signatureMatches; } /** @@ -328,7 +367,7 @@ public class ReflectionHelper { * @param type the type to convert. * @return the jdiff formatted string. */ - private static String typeToString(Type type) { + public static String typeToString(Type type) { if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; @@ -341,7 +380,9 @@ public class ReflectionHelper { for (Type t : types) { sb.append(typeToString(t)); if (++elementNum < types.length) { - sb.append(", "); + // Must match separator used in + // android.signature.cts.KtHelper.toDefaultTypeString. + sb.append(","); } } diff --git a/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java b/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java index dc3e44656c4..0a4558e70f4 100644 --- a/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java +++ b/tests/signature/tests/src/android/signature/cts/tests/ApiComplianceCheckerTest.java @@ -259,7 +259,7 @@ public class ApiComplianceCheckerTest extends AbstractApiCheckerTest<ApiComplian JDiffClassDescription clz = createClass(NormalClass.class.getSimpleName()); JDiffClassDescription.JDiffField field = new JDiffClassDescription.JDiffField( "VALUE_FIELD", "java.lang.String", - Modifier.PUBLIC | Modifier.FINAL | Modifier.STATIC, "\"\\u2708\""); + Modifier.PUBLIC | Modifier.FINAL | Modifier.STATIC, "\u2708"); clz.addField(field); checkSignatureCompliance(clz); assertEquals(field.toSignatureString(), "public static final java.lang.String VALUE_FIELD"); diff --git a/tests/tests/batterysaving/Android.bp b/tests/tests/batterysaving/Android.bp new file mode 100644 index 00000000000..a40bb604531 --- /dev/null +++ b/tests/tests/batterysaving/Android.bp @@ -0,0 +1,38 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +android_test { + name: "CtsBatterySavingTestCases", + defaults: ["cts_defaults"], + static_libs: [ + "BatterySavingCtsCommon", + "androidx.test.rules", + "androidx.legacy_legacy-support-v4", + "mockito-target-minus-junit4", + "compatibility-device-util-axt", + "ctstestrunner-axt", + "ub-uiautomator", + ], + libs: [ + "android.test.runner.stubs", + "android.test.base.stubs", + ], + srcs: ["src/**/*.java"], + test_suites: [ + "cts", + "vts", + "general-tests", + ], + sdk_version: "test_current", +} diff --git a/tests/tests/batterysaving/Android.mk b/tests/tests/batterysaving/Android.mk deleted file mode 100755 index 3dd2fbf4c5b..00000000000 --- a/tests/tests/batterysaving/Android.mk +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (C) 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := optional - -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - BatterySavingCtsCommon \ - androidx.test.rules \ - androidx.legacy_legacy-support-v4 \ - mockito-target-minus-junit4 \ - compatibility-device-util-axt \ - ctstestrunner-axt \ - ub-uiautomator - -LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CtsBatterySavingTestCases - -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -LOCAL_SDK_VERSION := test_current - -include $(BUILD_CTS_PACKAGE) - -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/tests/batterysaving/apps/Android.mk b/tests/tests/batterysaving/apps/Android.mk deleted file mode 100644 index 9aaa6acb0b1..00000000000 --- a/tests/tests/batterysaving/apps/Android.mk +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (C) 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/tests/batterysaving/apps/app_target_api_25/Android.bp b/tests/tests/batterysaving/apps/app_target_api_25/Android.bp new file mode 100644 index 00000000000..de783370f38 --- /dev/null +++ b/tests/tests/batterysaving/apps/app_target_api_25/Android.bp @@ -0,0 +1,27 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +android_test_helper_app { + name: "CtsBatterySavingAppTargetApi25", + defaults: ["cts_defaults"], + static_libs: ["CtsBatterSavingAppTargetLib"], + sdk_version: "test_current", + min_sdk_version: "23", + // tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} diff --git a/tests/tests/batterysaving/apps/app_target_api_25/Android.mk b/tests/tests/batterysaving/apps/app_target_api_25/Android.mk deleted file mode 100644 index c704a2923e7..00000000000 --- a/tests/tests/batterysaving/apps/app_target_api_25/Android.mk +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 := CtsBatterySavingAppTargetApi25 - -LOCAL_MODULE_TAGS := optional - -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -LOCAL_SRC_FILES := $(call all-java-files-under, ../app_target_api_current/src) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - BatterySavingCtsCommon \ - androidx.test.rules \ - androidx.legacy_legacy-support-v4 \ - mockito-target-minus-junit4 \ - compatibility-device-util-axt \ - ub-uiautomator - -LOCAL_SDK_VERSION := test_current -LOCAL_MIN_SDK_VERSION := 23 - -# tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_PACKAGE) diff --git a/tests/tests/batterysaving/apps/app_target_api_current/Android.bp b/tests/tests/batterysaving/apps/app_target_api_current/Android.bp new file mode 100644 index 00000000000..8d385c6cc9c --- /dev/null +++ b/tests/tests/batterysaving/apps/app_target_api_current/Android.bp @@ -0,0 +1,41 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +android_test_helper_app { + name: "CtsBatterySavingAppTargetApiCurrent", + defaults: ["cts_defaults"], + static_libs: ["CtsBatterSavingAppTargetLib"], + sdk_version: "test_current", + // tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], +} + +java_library { + name: "CtsBatterSavingAppTargetLib", + defaults: ["cts_defaults"], + srcs: ["src/**/*.java"], + static_libs: [ + "BatterySavingCtsCommon", + "androidx.test.rules", + "androidx.legacy_legacy-support-v4", + "mockito-target-minus-junit4", + "compatibility-device-util-axt", + "ub-uiautomator", + ], + sdk_version: "test_current", +} diff --git a/tests/tests/batterysaving/apps/app_target_api_current/Android.mk b/tests/tests/batterysaving/apps/app_target_api_current/Android.mk deleted file mode 100644 index 717ce3b73ce..00000000000 --- a/tests/tests/batterysaving/apps/app_target_api_current/Android.mk +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (C) 2018 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 := CtsBatterySavingAppTargetApiCurrent - -LOCAL_MODULE_TAGS := optional - -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_STATIC_JAVA_LIBRARIES := \ - BatterySavingCtsCommon \ - androidx.test.rules \ - androidx.legacy_legacy-support-v4 \ - mockito-target-minus-junit4 \ - compatibility-device-util-axt \ - ub-uiautomator - -LOCAL_SDK_VERSION := test_current - -# tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -include $(BUILD_CTS_PACKAGE) diff --git a/tests/tests/batterysaving/common/Android.bp b/tests/tests/batterysaving/common/Android.bp new file mode 100644 index 00000000000..6f99fda9aa1 --- /dev/null +++ b/tests/tests/batterysaving/common/Android.bp @@ -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. + +java_library { + name: "BatterySavingCtsCommon", + srcs: [ + "src/**/*.java", + "proto/**/*.proto", + ], + libs: [ + "androidx.test.rules", + "androidx.legacy_legacy-support-v4", + "mockito-target", + "compatibility-device-util-axt", + "android.test.runner.stubs", + ], + sdk_version: "test_current", + proto: { + type: "lite", + }, +} diff --git a/tests/tests/batterysaving/common/Android.mk b/tests/tests/batterysaving/common/Android.mk deleted file mode 100644 index 13284615666..00000000000 --- a/tests/tests/batterysaving/common/Android.mk +++ /dev/null @@ -1,36 +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 := \ - $(call all-java-files-under, src) \ - $(call all-proto-files-under, proto) - -LOCAL_JAVA_LIBRARIES := \ - androidx.test.rules \ - androidx.legacy_legacy-support-v4 \ - mockito-target \ - compatibility-device-util-axt \ - android.test.runner.stubs - -LOCAL_MODULE_TAGS := optional - -LOCAL_MODULE := BatterySavingCtsCommon - -LOCAL_SDK_VERSION := test_current - -include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java index 9afd501d322..d8218dee406 100644 --- a/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java +++ b/tests/tests/carrierapi/src/android/carrierapi/cts/NetworkScanApiTest.java @@ -323,19 +323,16 @@ public class NetworkScanApiTest { private NetworkScanRequest buildNetworkScanRequest(boolean includeBandsAndChannels) { // Make sure that there should be at least one entry. List<CellInfo> allCellInfo = mTelephonyManager.getAllCellInfo(); - if (allCellInfo == null) { - fail("TelephonyManager.getAllCellInfo() returned NULL!"); - } - if (allCellInfo.size() == 0) { - fail("TelephonyManager.getAllCellInfo() returned zero-length list!"); - } + List<RadioAccessSpecifier> radioAccessSpecifier = new ArrayList<>(); - // Construct a NetworkScanRequest - List<RadioAccessSpecifier> radioAccessSpecifier = getRadioAccessSpecifier(allCellInfo); - if (!includeBandsAndChannels) { - radioAccessSpecifier = radioAccessSpecifier.stream().map(spec -> + if (allCellInfo != null && allCellInfo.size() != 0) { + // Construct a NetworkScanRequest + radioAccessSpecifier = getRadioAccessSpecifier(allCellInfo); + if (!includeBandsAndChannels) { + radioAccessSpecifier = radioAccessSpecifier.stream().map(spec -> new RadioAccessSpecifier(spec.getRadioAccessNetwork(), null, null)) .collect(Collectors.toList()); + } } Log.d(TAG, "number of radioAccessSpecifier: " + radioAccessSpecifier.size()); diff --git a/tests/tests/graphics/Android.bp b/tests/tests/graphics/Android.bp new file mode 100644 index 00000000000..da6558d3868 --- /dev/null +++ b/tests/tests/graphics/Android.bp @@ -0,0 +1,43 @@ +// 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. + +android_test { + name: "CtsGraphicsTestCases", + defaults: ["cts_defaults"], + compile_multilib: "both", + libs: [ + "android.test.runner.stubs", + "android.test.base.stubs", + ], + static_libs: [ + "androidx.test.rules", + "mockito-target-minus-junit4", + "compatibility-device-util-axt", + "ctsdeviceutillegacy-axt", + "ctstestrunner-axt", + "androidx.annotation_annotation", + "junit", + "androidx.core_core", + ], + jni_libs: ["libctsgraphics_jni"], + srcs: ["src/**/*.java"], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + ], + // Enforce public / test api only + sdk_version: "test_current", +} diff --git a/tests/tests/graphics/Android.mk b/tests/tests/graphics/Android.mk deleted file mode 100644 index d3d10469e0e..00000000000 --- a/tests/tests/graphics/Android.mk +++ /dev/null @@ -1,51 +0,0 @@ -# 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. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE_TAGS := tests - -LOCAL_MULTILIB := both - -LOCAL_JAVA_LIBRARIES := android.test.runner.stubs android.test.base.stubs - -LOCAL_STATIC_JAVA_LIBRARIES += \ - androidx.test.rules \ - mockito-target-minus-junit4 \ - compatibility-device-util-axt \ - ctsdeviceutillegacy-axt \ - ctstestrunner-axt \ - androidx.annotation_annotation \ - junit - -LOCAL_STATIC_ANDROID_LIBRARIES += \ - androidx.core_core - -LOCAL_JNI_SHARED_LIBRARIES := libctsgraphics_jni - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CtsGraphicsTestCases - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests - -# Enforce public / test api only -LOCAL_SDK_VERSION := test_current - -include $(BUILD_CTS_PACKAGE) - -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/tests/graphics/jni/Android.bp b/tests/tests/graphics/jni/Android.bp new file mode 100644 index 00000000000..fdcbd4a6e4d --- /dev/null +++ b/tests/tests/graphics/jni/Android.bp @@ -0,0 +1,59 @@ +// Copyright 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. + +cc_test_library { + name: "libctsgraphics_jni", + gtest: false, + srcs: [ + "CtsGraphicsJniOnLoad.cpp", + "android_graphics_cts_ANativeWindowTest.cpp", + "android_graphics_cts_ASurfaceTextureTest.cpp", + "android_graphics_cts_BasicVulkanGpuTest.cpp", + "android_graphics_cts_BitmapTest.cpp", + "android_graphics_cts_SyncTest.cpp", + "android_graphics_cts_CameraGpuCtsActivity.cpp", + "android_graphics_cts_CameraVulkanGpuTest.cpp", + "android_graphics_cts_MediaVulkanGpuTest.cpp", + "android_graphics_cts_VulkanFeaturesTest.cpp", + "android_graphics_cts_VulkanPreTransformCtsActivity.cpp", + "CameraTestHelpers.cpp", + "ImageReaderTestHelpers.cpp", + "MediaTestHelpers.cpp", + "NativeTestHelpers.cpp", + "VulkanPreTransformTestHelpers.cpp", + "VulkanTestHelpers.cpp", + ], + cflags: [ + "-Wall", + "-Werror", + "-DGL_GLEXT_PROTOTYPES", + "-DEGL_EGLEXT_PROTOTYPES", + ], + static_libs: ["libvkjson_ndk"], + shared_libs: [ + "libandroid", + "libvulkan", + "libnativewindow", + "libsync", + "liblog", + "libdl", + "libjnigraphics", + "libcamera2ndk", + "libmediandk", + "libEGL", + "libGLESv2", + ], + stl: "c++_static", + sdk_version: "current", +} diff --git a/tests/tests/graphics/jni/Android.mk b/tests/tests/graphics/jni/Android.mk deleted file mode 100644 index 2906bf5d06f..00000000000 --- a/tests/tests/graphics/jni/Android.mk +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright 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_MODULE := libctsgraphics_jni - -LOCAL_MODULE_TAGS := tests - -LOCAL_SRC_FILES := \ - CtsGraphicsJniOnLoad.cpp \ - android_graphics_cts_ANativeWindowTest.cpp \ - android_graphics_cts_ASurfaceTextureTest.cpp \ - android_graphics_cts_BasicVulkanGpuTest.cpp \ - android_graphics_cts_BitmapTest.cpp \ - android_graphics_cts_SyncTest.cpp \ - android_graphics_cts_CameraGpuCtsActivity.cpp \ - android_graphics_cts_CameraVulkanGpuTest.cpp \ - android_graphics_cts_MediaVulkanGpuTest.cpp \ - android_graphics_cts_VulkanFeaturesTest.cpp \ - android_graphics_cts_VulkanPreTransformCtsActivity.cpp \ - CameraTestHelpers.cpp \ - ImageReaderTestHelpers.cpp \ - MediaTestHelpers.cpp \ - NativeTestHelpers.cpp \ - VulkanPreTransformTestHelpers.cpp \ - VulkanTestHelpers.cpp - -LOCAL_CFLAGS += -Wall -Werror -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES - -LOCAL_STATIC_LIBRARIES := libvkjson_ndk -LOCAL_SHARED_LIBRARIES := libandroid libvulkan libnativewindow libsync liblog libdl libjnigraphics \ - libcamera2ndk libmediandk libEGL libGLESv2 -LOCAL_NDK_STL_VARIANT := c++_static - -LOCAL_SDK_VERSION := current - -include $(BUILD_SHARED_LIBRARY) diff --git a/tests/tests/media/Android.bp b/tests/tests/media/Android.bp new file mode 100644 index 00000000000..9989b6b610a --- /dev/null +++ b/tests/tests/media/Android.bp @@ -0,0 +1,79 @@ +// 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. + +java_library { + name: "ctsmediautil", + srcs: [ + "src/android/media/cts/CodecImage.java", + "src/android/media/cts/YUVImage.java", + "src/android/media/cts/CodecUtils.java", + ], + sdk_version: "current", +} + +android_test { + name: "CtsMediaTestCases", + defaults: ["cts_defaults"], + // include both the 32 and 64 bit versions + compile_multilib: "both", + static_libs: [ + "compatibility-device-util-axt", + "ctsdeviceutillegacy-axt", + "ctsmediautil", + "ctstestrunner-axt", + "hamcrest-library", + "ctstestserver", + "junit", + "ndkaudio", + "testng", + "truth-prebuilt", + "mockito-target-minus-junit4", + "androidx.heifwriter_heifwriter", + "androidx.media_media", + ], + jni_libs: [ + "libaudio_jni", + "libc++", + "libctscodecutils_jni", + "libctsimagereader_jni", + "libctsmediadrm_jni", + "libctsmediacodec_jni", + "libnativehelper_compat_libc++", + "libndkaudioLib", + ], + // do not compress VP9 video files + aaptflags: [ + "-0 .vp9", + "-0 .ts", + "-0 .heic", + "-0 .trp", + ], + srcs: ["src/**/*.java"], + // This test uses private APIs + //sdk_version: "current", + platform_apis: true, + libs: [ + "org.apache.http.legacy", + "android.test.base.stubs", + "android.test.runner.stubs", + ], + // Tag this module as a cts test artifact + test_suites: [ + "cts", + "vts", + "general-tests", + "cts_instant", + ], + host_required: ["cts-dynamic-config"], +} diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk deleted file mode 100644 index ed41984e245..00000000000 --- a/tests/tests/media/Android.mk +++ /dev/null @@ -1,96 +0,0 @@ -# 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. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - src/android/media/cts/CodecImage.java \ - src/android/media/cts/YUVImage.java \ - src/android/media/cts/CodecUtils.java - -LOCAL_MODULE_TAGS := optional - -LOCAL_MODULE := ctsmediautil - -LOCAL_SDK_VERSION := current - -include $(BUILD_STATIC_JAVA_LIBRARY) - -include $(CLEAR_VARS) - -# don't include this package in any target -LOCAL_MODULE_TAGS := optional - -# and when built explicitly put it in the data partition -LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS) - -LOCAL_DEX_PREOPT := false - -LOCAL_PROGUARD_ENABLED := disabled - -# include both the 32 and 64 bit versions -LOCAL_MULTILIB := both - -LOCAL_STATIC_JAVA_LIBRARIES := \ - compatibility-device-util-axt \ - ctsdeviceutillegacy-axt \ - ctsmediautil \ - ctstestrunner-axt hamcrest-library \ - ctstestserver \ - junit \ - ndkaudio \ - testng \ - truth-prebuilt \ - mockito-target-minus-junit4 \ - androidx.heifwriter_heifwriter \ - androidx.media_media \ - -LOCAL_JNI_SHARED_LIBRARIES := \ - libaudio_jni \ - libc++ \ - libctscodecutils_jni \ - libctsimagereader_jni \ - libctsmediadrm_jni \ - libctsmediacodec_jni \ - libnativehelper_compat_libc++ \ - libndkaudioLib - -# do not compress VP9 video files -LOCAL_AAPT_FLAGS := -0 .vp9 -LOCAL_AAPT_FLAGS += -0 .ts -LOCAL_AAPT_FLAGS += -0 .heic - -LOCAL_SRC_FILES := $(call all-java-files-under, src) - -LOCAL_PACKAGE_NAME := CtsMediaTestCases - -# This test uses private APIs -#LOCAL_SDK_VERSION := current -LOCAL_PRIVATE_PLATFORM_APIS := true - -LOCAL_JAVA_LIBRARIES += \ - org.apache.http.legacy \ - android.test.base.stubs \ - android.test.runner.stubs - -# Tag this module as a cts test artifact -LOCAL_COMPATIBILITY_SUITE := cts vts general-tests cts_instant - -LOCAL_HOST_REQUIRED_MODULES := cts-dynamic-config - -include $(BUILD_CTS_PACKAGE) - -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/tests/tests/media/libaudiojni/Android.bp b/tests/tests/media/libaudiojni/Android.bp new file mode 100644 index 00000000000..6e1805c6bae --- /dev/null +++ b/tests/tests/media/libaudiojni/Android.bp @@ -0,0 +1,38 @@ +// 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. +// + +cc_test_library { + name: "libaudio_jni", + srcs: [ + "appendix-b-1-1-buffer-queue.cpp", + "appendix-b-1-2-recording.cpp", + "audio-record-native.cpp", + "audio-track-native.cpp", + "sl-utils.cpp", + ], + include_dirs: ["system/core/include"], + shared_libs: [ + "libandroid", + "liblog", + "libnativehelper_compat_libc++", + "libOpenSLES", + ], + stl: "libc++_static", + cflags: [ + "-Werror", + "-Wall", + ], + gtest: false, +} diff --git a/tests/tests/media/libaudiojni/Android.mk b/tests/tests/media/libaudiojni/Android.mk deleted file mode 100644 index af9d989e654..00000000000 --- a/tests/tests/media/libaudiojni/Android.mk +++ /dev/null @@ -1,42 +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) - -include $(CLEAR_VARS) - -LOCAL_MODULE := libaudio_jni - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - appendix-b-1-1-buffer-queue.cpp \ - appendix-b-1-2-recording.cpp \ - audio-record-native.cpp \ - audio-track-native.cpp \ - sl-utils.cpp - -LOCAL_C_INCLUDES := \ - $(JNI_H_INCLUDE) \ - system/core/include - -LOCAL_C_INCLUDES += $(call include-path-for, libaudiojni) \ - $(call include-path-for, wilhelm) - -LOCAL_SHARED_LIBRARIES := libandroid liblog libnativehelper_compat_libc++ libOpenSLES -LOCAL_CXX_STL := libc++ - -LOCAL_CFLAGS := -Werror -Wall - -include $(BUILD_SHARED_LIBRARY) diff --git a/tests/tests/media/libimagereaderjni/Android.bp b/tests/tests/media/libimagereaderjni/Android.bp new file mode 100644 index 00000000000..9dd0988c45c --- /dev/null +++ b/tests/tests/media/libimagereaderjni/Android.bp @@ -0,0 +1,32 @@ +// Copyright 2017 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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 the unit tests. + +cc_test_library { + name: "libctsimagereader_jni", + srcs: ["AImageReaderCts.cpp"], + shared_libs: [ + "libandroid", + "libcamera2ndk", + "libmediandk", + "libnativewindow", + "liblog", + ], + cflags: [ + "-Werror", + "-Wall", + ], + gtest: false, +} diff --git a/tests/tests/media/libimagereaderjni/Android.mk b/tests/tests/media/libimagereaderjni/Android.mk deleted file mode 100644 index 6ce591c09f1..00000000000 --- a/tests/tests/media/libimagereaderjni/Android.mk +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2017 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT 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 the unit tests. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := libctsimagereader_jni - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - AImageReaderCts.cpp - -LOCAL_SHARED_LIBRARIES := \ - libandroid \ - libcamera2ndk \ - libmediandk \ - libnativewindow \ - liblog - -LOCAL_CXX_STL := libc++ - -LOCAL_CFLAGS := -Werror -Wall - -include $(BUILD_SHARED_LIBRARY) diff --git a/tests/tests/media/libmediandkjni/Android.bp b/tests/tests/media/libmediandkjni/Android.bp new file mode 100644 index 00000000000..109a488c384 --- /dev/null +++ b/tests/tests/media/libmediandkjni/Android.bp @@ -0,0 +1,94 @@ +// Copyright (C) 2012 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +//------------------------------------------------------------------------------ +// Builds libctscodecutils_jni.so +// +cc_test_library { + name: "libctscodecutils_jni", + srcs: [ + "codec-utils-jni.cpp", + "md5_utils.cpp", + ], + include_dirs: ["system/core/include"], + shared_libs: [ + "libnativehelper_compat_libc++", + "liblog", + ], + sdk_version: "current", + cflags: [ + "-Werror", + "-Wall", + "-DEGL_EGLEXT_PROTOTYPES", + ], + gtest: false, +} + +//------------------------------------------------------------------------------ +// Builds libctsmediacodec_jni.so +// +cc_test_library { + name: "libctsmediacodec_jni", + srcs: [ + "native-media-jni.cpp", + "native_media_utils.cpp", + "native_media_decoder_source.cpp", + "native_media_encoder_jni.cpp", + ], + include_dirs: ["system/core/include"], + shared_libs: [ + "libandroid", + "libnativehelper_compat_libc++", + "liblog", + "libmediandk", + "libEGL", + ], + stl: "libc++_static", + cflags: [ + "-Werror", + "-Wall", + "-DEGL_EGLEXT_PROTOTYPES", + ], + gtest: false, +} + +//------------------------------------------------------------------------------ +// Builds libctsmediadrm_jni.so +// +cc_test_library { + name: "libctsmediadrm_jni", + srcs: [ + "CtsMediaDrmJniOnLoad.cpp", + "codec-utils-jni.cpp", + "md5_utils.cpp", + "native-mediadrm-jni.cpp", + ], + include_dirs: ["system/core/include"], + shared_libs: [ + "libandroid", + "libnativehelper_compat_libc++", + "liblog", + "libmediandk", + "libdl", + "libEGL", + ], + cflags: [ + "-Werror", + "-Wall", + "-DEGL_EGLEXT_PROTOTYPES", + ], + stl: "libc++_static", + gtest: false, +} diff --git a/tests/tests/media/libmediandkjni/Android.mk b/tests/tests/media/libmediandkjni/Android.mk deleted file mode 100644 index 993f1772122..00000000000 --- a/tests/tests/media/libmediandkjni/Android.mk +++ /dev/null @@ -1,111 +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) - -#------------------------------------------------------------------------------ -# Builds libctscodecutils_jni.so -# -include $(CLEAR_VARS) - -LOCAL_MODULE := libctscodecutils_jni - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - codec-utils-jni.cpp \ - md5_utils.cpp - -LOCAL_C_INCLUDES := \ - $(JNI_H_INCLUDE) \ - system/core/include - -LOCAL_C_INCLUDES += $(call include-path-for, mediandk) - -LOCAL_SHARED_LIBRARIES := \ - libnativehelper_compat_libc++ \ - liblog - -LOCAL_SDK_VERSION := current - -LOCAL_NDK_STL_VARIANT := system - -LOCAL_CFLAGS := -Werror -Wall -DEGL_EGLEXT_PROTOTYPES - -include $(BUILD_SHARED_LIBRARY) - -#------------------------------------------------------------------------------ -# Builds libctsmediacodec_jni.so -# -include $(CLEAR_VARS) - -LOCAL_MODULE := libctsmediacodec_jni - -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - native-media-jni.cpp \ - native_media_utils.cpp \ - native_media_decoder_source.cpp \ - native_media_encoder_jni.cpp - -LOCAL_C_INCLUDES := \ - $(JNI_H_INCLUDE) \ - system/core/include - -LOCAL_C_INCLUDES += $(call include-path-for, mediandk) - -LOCAL_SHARED_LIBRARIES := \ - libandroid libnativehelper_compat_libc++ \ - liblog libmediandk libEGL - -LOCAL_CXX_STL := libc++ - -LOCAL_CFLAGS := -Werror -Wall -DEGL_EGLEXT_PROTOTYPES - -include $(BUILD_SHARED_LIBRARY) - - -#------------------------------------------------------------------------------ -# Builds libctsmediadrm_jni.so -# -include $(CLEAR_VARS) - -LOCAL_MODULE := libctsmediadrm_jni - -# Don't include this package in any configuration by default. -LOCAL_MODULE_TAGS := optional - -LOCAL_SRC_FILES := \ - CtsMediaDrmJniOnLoad.cpp \ - codec-utils-jni.cpp \ - md5_utils.cpp \ - native-mediadrm-jni.cpp \ - -LOCAL_C_INCLUDES := \ - $(JNI_H_INCLUDE) \ - system/core/include - - -LOCAL_C_INCLUDES += $(call include-path-for, mediandk) - -LOCAL_SHARED_LIBRARIES := \ - libandroid libnativehelper_compat_libc++ \ - liblog libmediandk libdl libEGL - -LOCAL_CFLAGS := -Werror -Wall -DEGL_EGLEXT_PROTOTYPES - -LOCAL_CXX_STL := libc++ - -include $(BUILD_SHARED_LIBRARY) diff --git a/tests/tests/media/libndkaudio/Android.bp b/tests/tests/media/libndkaudio/Android.bp new file mode 100644 index 00000000000..2746f0d640f --- /dev/null +++ b/tests/tests/media/libndkaudio/Android.bp @@ -0,0 +1,54 @@ +// 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. +// + +cc_test_library { + name: "libndkaudioLib", + include_dirs: [ + "frameworks/wilhelm/include", + "frameworks/wilhelm/src/android", + ], + srcs: [ + "OpenSLESUtils.cpp", + "AudioPlayer.cpp", + "AudioSource.cpp", + "PeriodicAudioSource.cpp", + "SystemParams.cpp", + "WaveTableGenerator.cpp", + "WaveTableOscillator.cpp", + "com_android_ndkaudio_AudioPlayer.cpp", + "AudioRecorder.cpp", + "com_android_ndkaudio_AudioRecorder.cpp", + ], + stl: "libc++_static", + shared_libs: [ + "liblog", + "libOpenSLES", + ], + cflags: [ + "-Werror", + "-Wall", + ], + gtest: false, +} + +// +// ndkaudio - java +// +java_library { + name: "ndkaudio", + srcs: ["**/*.java"], + sdk_version: "current", + min_sdk_version: "23", +} diff --git a/tests/tests/media/libndkaudio/Android.mk b/tests/tests/media/libndkaudio/Android.mk deleted file mode 100644 index 9480dcd725b..00000000000 --- a/tests/tests/media/libndkaudio/Android.mk +++ /dev/null @@ -1,62 +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_MODULE := libndkaudioLib - -LOCAL_MODULE_TAGS := optional - -LOCAL_C_INCLUDES := \ - frameworks/wilhelm/include \ - frameworks/wilhelm/src/android \ - $(call include-path-for, wilhelm) - -LOCAL_SRC_FILES := \ - OpenSLESUtils.cpp \ - AudioPlayer.cpp \ - AudioSource.cpp \ - PeriodicAudioSource.cpp \ - SystemParams.cpp \ - WaveTableGenerator.cpp \ - WaveTableOscillator.cpp \ - com_android_ndkaudio_AudioPlayer.cpp \ - AudioRecorder.cpp \ - com_android_ndkaudio_AudioRecorder.cpp - -LOCAL_CXX_STL := libc++ - -LOCAL_SHARED_LIBRARIES := liblog libOpenSLES - -LOCAL_CFLAGS := -Werror -Wall - -include $(BUILD_SHARED_LIBRARY) - -# -# ndkaudio - java -# -include $(CLEAR_VARS) - -LOCAL_MODULE := ndkaudio - -LOCAL_SRC_FILES := $(call all-subdir-java-files) - -LOCAL_CERTIFICATE := platform - -LOCAL_SDK_VERSION := current -LOCAL_MIN_SDK_VERSION := 23 - -include $(BUILD_STATIC_JAVA_LIBRARY) diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java index 16ced50dd40..9fedbbffc25 100755 --- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java +++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java @@ -367,7 +367,7 @@ public class UiAutomationTest extends InstrumentationTestCase { uiAutomation.destroy(); assertTrue(UiAutomationTestA11yService.sConnectedInstance.isConnected()); getInstrumentation().getUiAutomation(); // Should suppress - assertFalse(UiAutomationTestA11yService.sConnectedInstance.isConnected()); + waitForAccessibilityServiceToUnbind(); } finally { turnAccessibilityOff(); } @@ -385,7 +385,7 @@ public class UiAutomationTest extends InstrumentationTestCase { UiAutomation suppressingUiAutomation = getInstrumentation().getUiAutomation(); // We verify above that the connection is broken here. Make sure we see a new one // after we destroy it - UiAutomationTestA11yService.sConnectedInstance = null; + waitForAccessibilityServiceToUnbind(); suppressingUiAutomation.destroy(); waitForAccessibilityServiceToStart(); } finally { @@ -404,7 +404,7 @@ public class UiAutomationTest extends InstrumentationTestCase { getInstrumentation().getUiAutomation(); // We verify above that the connection is broken here. Make sure we see a new one // after we change the flags - UiAutomationTestA11yService.sConnectedInstance = null; + waitForAccessibilityServiceToUnbind(); getInstrumentation() .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES); waitForAccessibilityServiceToStart(); @@ -471,12 +471,12 @@ public class UiAutomationTest extends InstrumentationTestCase { private void waitForAccessibilityServiceToStart() { long timeoutTimeMillis = SystemClock.uptimeMillis() + TIMEOUT_FOR_SERVICE_ENABLE; while (SystemClock.uptimeMillis() < timeoutTimeMillis) { - synchronized(UiAutomationTestA11yService.sWaitObjectForConnecting) { + synchronized(UiAutomationTestA11yService.sWaitObjectForConnectOrUnbind) { if (UiAutomationTestA11yService.sConnectedInstance != null) { return; } try { - UiAutomationTestA11yService.sWaitObjectForConnecting.wait( + UiAutomationTestA11yService.sWaitObjectForConnectOrUnbind.wait( timeoutTimeMillis - SystemClock.uptimeMillis()); } catch (InterruptedException e) { // Ignored; loop again @@ -486,6 +486,24 @@ public class UiAutomationTest extends InstrumentationTestCase { throw new RuntimeException("Test accessibility service not starting"); } + private void waitForAccessibilityServiceToUnbind() { + long timeoutTimeMillis = SystemClock.uptimeMillis() + TIMEOUT_FOR_SERVICE_ENABLE; + while (SystemClock.uptimeMillis() < timeoutTimeMillis) { + synchronized(UiAutomationTestA11yService.sWaitObjectForConnectOrUnbind) { + if (UiAutomationTestA11yService.sConnectedInstance == null) { + return; + } + try { + UiAutomationTestA11yService.sWaitObjectForConnectOrUnbind.wait( + timeoutTimeMillis - SystemClock.uptimeMillis()); + } catch (InterruptedException e) { + // Ignored; loop again + } + } + } + throw new RuntimeException("Test accessibility service doesn't unbind"); + } + private void turnAccessibilityOff() { getInstrumentation().getUiAutomation().destroy(); final Object waitLockForA11yOff = new Object(); @@ -504,7 +522,6 @@ public class UiAutomationTest extends InstrumentationTestCase { ContentResolver cr = context.getContentResolver(); Settings.Secure.putString( cr, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, null); - UiAutomationTestA11yService.sConnectedInstance = null; long timeoutTimeMillis = SystemClock.uptimeMillis() + TIMEOUT_FOR_SERVICE_ENABLE; while (SystemClock.uptimeMillis() < timeoutTimeMillis) { synchronized (waitLockForA11yOff) { diff --git a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestA11yService.java b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestA11yService.java index ca598bcfc27..e70878426a1 100644 --- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestA11yService.java +++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTestA11yService.java @@ -15,6 +15,8 @@ package android.app.uiautomation.cts; import android.accessibilityservice.AccessibilityService; +import android.content.Intent; +import android.util.Log; import android.view.accessibility.AccessibilityEvent; /** @@ -22,12 +24,24 @@ import android.view.accessibility.AccessibilityEvent; * services */ public class UiAutomationTestA11yService extends AccessibilityService { - public static Object sWaitObjectForConnecting = new Object(); + private static String LOG_TAG = "UiAutomationTest"; + public static Object sWaitObjectForConnectOrUnbind = new Object(); public static UiAutomationTestA11yService sConnectedInstance; @Override + public boolean onUnbind(Intent intent) { + synchronized (sWaitObjectForConnectOrUnbind) { + sConnectedInstance = null; + sWaitObjectForConnectOrUnbind.notifyAll(); + } + Log.v(LOG_TAG, "onUnbind [" + this + "]"); + return false; + } + + @Override public void onDestroy() { + Log.v(LOG_TAG, "onDestroy [" + this + "]"); } @Override @@ -41,10 +55,11 @@ public class UiAutomationTestA11yService extends AccessibilityService { @Override protected void onServiceConnected() { - synchronized (sWaitObjectForConnecting) { + synchronized (sWaitObjectForConnectOrUnbind) { sConnectedInstance = this; - sWaitObjectForConnecting.notifyAll(); + sWaitObjectForConnectOrUnbind.notifyAll(); } + Log.v(LOG_TAG, "onServiceConnected [" + this + "]"); } public boolean isConnected() { |