diff options
Diffstat (limited to 'api')
| -rw-r--r-- | api/Android.bp | 122 | ||||
| -rw-r--r-- | api/Android.mk | 2 | ||||
| -rw-r--r-- | api/ApiDocs.bp | 516 | ||||
| -rw-r--r-- | api/OWNERS | 4 | ||||
| -rw-r--r-- | api/StubLibraries.bp | 600 | ||||
| -rw-r--r-- | api/api.go | 219 | ||||
| -rw-r--r-- | api/api_test.go | 68 | ||||
| -rwxr-xr-x | api/api_versions_trimmer.py | 136 | ||||
| -rw-r--r-- | api/api_versions_trimmer_unittests.py | 307 | ||||
| l--------- | api/docs | 1 |
10 files changed, 1435 insertions, 540 deletions
diff --git a/api/Android.bp b/api/Android.bp index 89993e751cf0..f5bafe8bf8da 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -31,49 +31,18 @@ bootstrap_go_package { "blueprint", "soong", "soong-android", + "soong-bp2build", "soong-genrule", "soong-java", ], srcs: ["api.go"], + testSrcs: ["api_test.go"], pluginFor: ["soong_build"], } -python_defaults { - name: "python3_version_defaults", - version: { - py2: { - enabled: false, - }, - py3: { - enabled: true, - embedded_launcher: false, - }, - }, -} - -python_binary_host { - name: "api_versions_trimmer", - srcs: ["api_versions_trimmer.py"], - defaults: ["python3_version_defaults"], -} - -python_test_host { - name: "api_versions_trimmer_unittests", - main: "api_versions_trimmer_unittests.py", - srcs: [ - "api_versions_trimmer_unittests.py", - "api_versions_trimmer.py", - ], - defaults: ["python3_version_defaults"], - test_options: { - unit_test: true, - }, -} - python_binary_host { name: "merge_annotation_zips", srcs: ["merge_annotation_zips.py"], - defaults: ["python3_version_defaults"], } python_test_host { @@ -83,7 +52,6 @@ python_test_host { "merge_annotation_zips.py", "merge_annotation_zips_test.py", ], - defaults: ["python3_version_defaults"], test_options: { unit_test: true, }, @@ -112,9 +80,12 @@ combined_apis { "framework-adservices", "framework-appsearch", "framework-bluetooth", + "framework-configinfrastructure", "framework-connectivity", "framework-connectivity-t", + "framework-devicelock", "framework-graphics", + "framework-healthfitness", "framework-media", "framework-mediaprovider", "framework-ondevicepersonalization", @@ -126,12 +97,17 @@ combined_apis { "framework-sdksandbox", "framework-tethering", "framework-uwb", + "framework-virtualization", "framework-wifi", "i18n.module.public.api", ], system_server_classpath: [ + "service-art", + "service-configinfrastructure", + "service-healthfitness", "service-media-s", "service-permission", + "service-rkp", "service-sdksandbox", ], } @@ -194,6 +170,67 @@ genrule { } genrule { + name: "frameworks-base-api-current.srcjar", + tools: ["merge_zips"], + out: ["current.srcjar"], + cmd: "$(location merge_zips) $(out) $(in)", + srcs: [ + ":api-stubs-docs-non-updatable", + ":all-modules-public-stubs-source", + ], + visibility: ["//visibility:private"], // Used by make module in //development, mind +} + +// This produces the same annotations.zip as framework-doc-stubs, but by using +// outputs from individual modules instead of all the source code. +genrule_defaults { + name: "sdk-annotations-defaults", + out: ["annotations.zip"], + tools: [ + "merge_annotation_zips", + "soong_zip", + ], + cmd: "$(location merge_annotation_zips) $(genDir)/out $(in) && " + + "$(location soong_zip) -o $(out) -C $(genDir)/out -D $(genDir)/out", +} + +genrule { + name: "sdk-annotations.zip", + defaults: ["sdk-annotations-defaults"], + srcs: [ + ":android-non-updatable-doc-stubs{.annotations.zip}", + ":all-modules-public-annotations", + ], +} + +genrule { + name: "sdk-annotations-system.zip", + defaults: ["sdk-annotations-defaults"], + srcs: [ + ":android-non-updatable-doc-stubs-system{.annotations.zip}", + ":all-modules-system-annotations", + ], +} + +genrule { + name: "sdk-annotations-module-lib.zip", + defaults: ["sdk-annotations-defaults"], + srcs: [ + ":android-non-updatable-doc-stubs-module-lib{.annotations.zip}", + ":all-modules-module-lib-annotations", + ], +} + +genrule { + name: "sdk-annotations-system-server.zip", + defaults: ["sdk-annotations-defaults"], + srcs: [ + ":android-non-updatable-doc-stubs-system-server{.annotations.zip}", + ":all-modules-system-server-annotations", + ], +} + +genrule { name: "combined-removed-dex", visibility: [ "//frameworks/base/boot", @@ -209,3 +246,20 @@ genrule { out: ["combined-removed-dex.txt"], cmd: "$(location gen_combined_removed_dex.sh) $(location metalava) $(genDir) $(in) > $(out)", } + +java_genrule { + name: "api_fingerprint", + srcs: [ + ":frameworks-base-api-current.txt", + ":frameworks-base-api-system-current.txt", + ":frameworks-base-api-module-lib-current.txt", + ":frameworks-base-api-system-server-current.txt", + ], + out: ["api_fingerprint.txt"], + cmd: "cat $(in) | md5sum | cut -d' ' -f1 > $(out)", +} + +build = [ + "ApiDocs.bp", + "StubLibraries.bp", +] diff --git a/api/Android.mk b/api/Android.mk new file mode 100644 index 000000000000..ce5f995033c5 --- /dev/null +++ b/api/Android.mk @@ -0,0 +1,2 @@ +.PHONY: checkapi +checkapi: frameworks-base-api-current-compat frameworks-base-api-system-current-compat frameworks-base-api-module-lib-current-compat diff --git a/api/ApiDocs.bp b/api/ApiDocs.bp new file mode 100644 index 000000000000..fbcaa52f9bb4 --- /dev/null +++ b/api/ApiDocs.bp @@ -0,0 +1,516 @@ +// 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. + +// How API docs are generated: +// +// raw source files --(metalava)--> stub source files --(doclava)--> API doc +// +// The metalava conversion is done by droidstub modules framework-doc-*-stubs. +// The API doc generation is done by the various droiddoc modules each of which +// is for different format. + +///////////////////////////////////////////////////////////////////// +// stub source files are generated using metalava +///////////////////////////////////////////////////////////////////// + +framework_docs_only_libs = [ + "voip-common", + "android.test.mock", + "android-support-annotations", + "android-support-compat", + "android-support-core-ui", + "android-support-core-utils", + "android-support-design", + "android-support-dynamic-animation", + "android-support-exifinterface", + "android-support-fragment", + "android-support-media-compat", + "android-support-percent", + "android-support-transition", + "android-support-v7-cardview", + "android-support-v7-gridlayout", + "android-support-v7-mediarouter", + "android-support-v7-palette", + "android-support-v7-preference", + "android-support-v13", + "android-support-v14-preference", + "android-support-v17-leanback", + "android-support-vectordrawable", + "android-support-animatedvectordrawable", + "android-support-v7-appcompat", + "android-support-v7-recyclerview", + "android-support-v8-renderscript", + "android-support-multidex", + "android-support-multidex-instrumentation", +] + +// These defaults enable doc-stub generation, api lint database generation and sdk value generation. +stubs_defaults { + name: "android-non-updatable-doc-stubs-defaults", + defaults: ["android-non-updatable-stubs-defaults"], + srcs: [ + // No longer part of the stubs, but are included in the docs. + ":android-test-base-sources", + ":android-test-mock-sources", + ":android-test-runner-sources", + ], + libs: framework_docs_only_libs, + create_doc_stubs: true, + write_sdk_values: true, +} + +// Defaults module for doc-stubs targets that use module source code as input. +stubs_defaults { + name: "framework-doc-stubs-sources-default", + defaults: ["android-non-updatable-doc-stubs-defaults"], + srcs: [ + ":art.module.public.api{.public.stubs.source}", + ":conscrypt.module.public.api{.public.stubs.source}", + ":i18n.module.public.api{.public.stubs.source}", + + ":framework-adservices-sources", + ":framework-appsearch-sources", + ":framework-connectivity-sources", + ":framework-bluetooth-sources", + ":framework-connectivity-tiramisu-updatable-sources", + ":framework-graphics-srcs", + ":framework-mediaprovider-sources", + ":framework-nearby-sources", + ":framework-ondevicepersonalization-sources", + ":framework-permission-sources", + ":framework-permission-s-sources", + ":framework-scheduling-sources", + ":framework-sdkextensions-sources", + ":framework-statsd-sources", + ":framework-sdksandbox-sources", + ":framework-tethering-srcs", + ":framework-uwb-updatable-sources", + ":framework-wifi-updatable-sources", + ":ike-srcs", + ":updatable-media-srcs", + ], +} + +droidstubs { + name: "android-non-updatable-doc-stubs", + defaults: [ + "android-non-updatable-doc-stubs-defaults", + "module-classpath-stubs-defaults", + ], + args: metalava_framework_docs_args, +} + +droidstubs { + name: "android-non-updatable-doc-stubs-system", + defaults: [ + "android-non-updatable-doc-stubs-defaults", + "module-classpath-stubs-defaults", + ], + args: metalava_framework_docs_args + + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ", +} + +droidstubs { + name: "android-non-updatable-doc-stubs-module-lib", + defaults: [ + "android-non-updatable-doc-stubs-defaults", + "module-classpath-stubs-defaults", + ], + args: metalava_framework_docs_args + + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) " + + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES\\) ", + generate_stubs: false, // We're only using this module for the annotations.zip output, disable doc-stubs. + write_sdk_values: false, +} + +droidstubs { + name: "android-non-updatable-doc-stubs-system-server", + defaults: [ + "android-non-updatable-doc-stubs-defaults", + "module-classpath-stubs-defaults", + ], + args: metalava_framework_docs_args + + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) " + + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES\\) " + + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.SYSTEM_SERVER\\) ", + generate_stubs: false, // We're only using this module for the annotations.zip output, disable doc-stubs. + write_sdk_values: false, +} + +droidstubs { + name: "framework-doc-stubs", + defaults: ["android-non-updatable-doc-stubs-defaults"], + srcs: [":all-modules-public-stubs-source"], + args: metalava_framework_docs_args, + api_levels_module: "api_versions_public", + aidl: { + include_dirs: [ + "packages/modules/Connectivity/framework/aidl-export", + "packages/modules/Media/apex/aidl/stable", + ], + }, + extensions_info_file: ":sdk-extensions-info", +} + +droidstubs { + name: "framework-doc-system-stubs", + defaults: ["framework-doc-stubs-sources-default"], + args: metalava_framework_docs_args + + " --show-annotation android.annotation.SystemApi\\(client=android.annotation.SystemApi.Client.PRIVILEGED_APPS\\) ", + api_levels_annotations_enabled: true, + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", + ], + api_levels_sdk_type: "system", + extensions_info_file: ":sdk-extensions-info", +} + +///////////////////////////////////////////////////////////////////// +// API docs are created from the generated stub source files +// using droiddoc +///////////////////////////////////////////////////////////////////// + +framework_docs_only_args = " -android -manifest $(location :frameworks-base-core-AndroidManifest.xml) " + + "-metalavaApiSince " + + "-werror -lerror -hide 111 -hide 113 -hide 125 -hide 126 -hide 127 -hide 128 " + + "-overview $(location :frameworks-base-java-overview) " + + // Federate Support Library references against local API file. + "-federate SupportLib https://developer.android.com " + + "-federationapi SupportLib $(location :current-support-api) " + + // Federate Support Library references against local API file. + "-federate AndroidX https://developer.android.com " + + "-federationapi AndroidX $(location :current-androidx-api) " + +doc_defaults { + name: "framework-docs-default", + libs: framework_docs_only_libs + [ + "stub-annotations", + "unsupportedappusage", + ], + html_dirs: [ + "docs/html", + ], + knowntags: [ + "docs/knowntags.txt", + ":art.module.public.api{.doctags}", + ], + custom_template: "droiddoc-templates-sdk", + resourcesdir: "docs/html/reference/images/", + resourcesoutdir: "reference/android/images/", + hdf: [ + "dac true", + "sdk.codename O", + "sdk.preview.version 1", + "sdk.version 7.0", + "sdk.rel.id 1", + "sdk.preview 0", + ], + arg_files: [ + ":frameworks-base-core-AndroidManifest.xml", + ":frameworks-base-java-overview", + ":current-support-api", + ":current-androidx-api", + ], + // TODO(b/169090544): remove below aidl includes. + aidl: { + include_dirs: [ + "frameworks/av/aidl", + "frameworks/base/media/aidl", + "frameworks/native/libs/permission/aidl", + ], + }, +} + +doc_defaults { + name: "framework-dokka-docs-default", +} + +droiddoc { + name: "doc-comment-check-docs", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], + args: framework_docs_only_args + " -referenceonly -parsecomments", + installable: false, +} + +droiddoc { + name: "offline-sdk-docs", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], + hdf: [ + "android.whichdoc offline", + ], + compat_config: ":global-compat-config", + proofread_file: "offline-sdk-docs-proofread.txt", + args: framework_docs_only_args + " -offlinemode -title \"Android SDK\"", + static_doc_index_redirect: "docs/docs-preview-index.html", +} + +droiddoc { + // Please sync with android-api-council@ before making any changes for the name property below. + // Since there's cron jobs that fetch offline-sdk-referenceonly-docs-docs.zip periodically. + // See b/116221385 for reference. + name: "offline-sdk-referenceonly-docs", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], + hdf: [ + "android.whichdoc offline", + ], + proofread_file: "offline-sdk-referenceonly-docs-proofread.txt", + args: framework_docs_only_args + " -offlinemode -title \"Android SDK\" -referenceonly", + static_doc_index_redirect: "docs/docs-documentation-redirect.html", + static_doc_properties: "docs/source.properties", +} + +droiddoc { + // Please sync with android-api-council@ before making any changes for the name property below. + // Since there's cron jobs that fetch offline-system-sdk-referenceonly-docs-docs.zip periodically. + // See b/116221385 for reference. + name: "offline-system-sdk-referenceonly-docs", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-system-stubs", + ], + hdf: [ + "android.whichdoc offline", + ], + proofread_file: "offline-system-sdk-referenceonly-docs-proofread.txt", + args: framework_docs_only_args + " -hide 101 -hide 104 -hide 108" + + " -offlinemode -title \"Android System SDK\" -referenceonly", + static_doc_index_redirect: "docs/docs-documentation-redirect.html", + static_doc_properties: "docs/source.properties", +} + +droiddoc { + name: "online-sdk-docs", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], + hdf: [ + "android.whichdoc online", + "android.hasSamples true", + ], + proofread_file: "online-sdk-docs-proofread.txt", + args: framework_docs_only_args + + " -toroot / -samplegroup Admin " + + " -samplegroup Background " + + " -samplegroup Connectivity " + + " -samplegroup Content " + + " -samplegroup Input " + + " -samplegroup Media " + + " -samplegroup Notification " + + " -samplegroup RenderScript " + + " -samplegroup Security " + + " -samplegroup Sensors " + + " -samplegroup System " + + " -samplegroup Testing " + + " -samplegroup UI " + + " -samplegroup Views " + + " -samplegroup Wearable -samplesdir development/samples/browseable ", +} + +droiddoc { + name: "online-system-api-sdk-docs", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-system-stubs", + ], + hdf: [ + "android.whichdoc online", + "android.hasSamples true", + ], + proofread_file: "online-system-api-sdk-docs-proofread.txt", + args: framework_docs_only_args + + " -referenceonly " + + " -title \"Android SDK - Including system APIs.\" " + + " -hide 101 " + + " -hide 104 " + + " -hide 108 " + + " -toroot / -samplegroup Admin " + + " -samplegroup Background " + + " -samplegroup Connectivity " + + " -samplegroup Content " + + " -samplegroup Input " + + " -samplegroup Media " + + " -samplegroup Notification " + + " -samplegroup RenderScript " + + " -samplegroup Security " + + " -samplegroup Sensors " + + " -samplegroup System " + + " -samplegroup Testing " + + " -samplegroup UI " + + " -samplegroup Views " + + " -samplegroup Wearable -samplesdir development/samples/browseable ", + installable: false, +} + +droiddoc { + name: "ds-docs-java", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], + hdf: [ + "android.whichdoc online", + "android.hasSamples true", + ], + proofread_file: "ds-docs-proofread.txt", + args: framework_docs_only_args + + " -toroot / -yamlV2 -samplegroup Admin " + + " -samplegroup Background " + + " -samplegroup Connectivity " + + " -samplegroup Content " + + " -samplegroup Input " + + " -samplegroup Media " + + " -samplegroup Notification " + + " -samplegroup RenderScript " + + " -samplegroup Security " + + " -samplegroup Sensors " + + " -samplegroup System " + + " -samplegroup Testing " + + " -samplegroup UI " + + " -samplegroup Views " + + " -samplegroup Wearable -devsite -samplesdir development/samples/browseable ", +} + +droiddoc { + name: "ds-docs-kt", + defaults: ["framework-dokka-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], + args: "-noJdkLink -links https://kotlinlang.org/api/latest/jvm/stdlib/^external/dokka/package-list " + + "-noStdlibLink", + proofread_file: "ds-dokka-proofread.txt", + dokka_enabled: true, +} + +java_genrule { + name: "ds-docs", + tools: [ + "zip2zip", + "merge_zips", + ], + srcs: [ + ":ds-docs-java{.docs.zip}", + ":ds-docs-kt{.docs.zip}", + ], + out: ["ds-docs.zip"], + dist: { + targets: ["docs"], + }, + cmd: "$(location zip2zip) -i $(location :ds-docs-kt{.docs.zip}) -o $(genDir)/ds-docs-kt-moved.zip **/*:en/reference/kotlin && " + + "$(location merge_zips) $(out) $(location :ds-docs-java{.docs.zip}) $(genDir)/ds-docs-kt-moved.zip", +} + +java_genrule { + name: "ds-docs-switched", + tools: [ + "switcher4", + "soong_zip", + ], + srcs: [ + ":ds-docs-java{.docs.zip}", + ":ds-docs-kt{.docs.zip}", + ], + out: ["ds-docs-switched.zip"], + dist: { + targets: ["docs"], + }, + cmd: "unzip -q $(location :ds-docs-java{.docs.zip}) -d $(genDir) && " + + "unzip -q $(location :ds-docs-kt{.docs.zip}) -d $(genDir)/en/reference/kotlin && " + + "SWITCHER=$$(cd $$(dirname $(location switcher4)) && pwd)/$$(basename $(location switcher4)) && " + + "(cd $(genDir)/en/reference && $$SWITCHER --work platform) > /dev/null && " + + "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)", +} + +droiddoc { + name: "ds-static-docs", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], + hdf: [ + "android.whichdoc online", + ], + args: framework_docs_only_args + + " -staticonly " + + " -toroot / " + + " -devsite " + + " -ignoreJdLinks ", +} + +droiddoc { + name: "ds-ref-navtree-docs", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], + hdf: [ + "android.whichdoc online", + ], + args: framework_docs_only_args + + " -toroot / " + + " -atLinksNavtree " + + " -navtreeonly ", +} + +droiddoc { + name: "online-sdk-dev-docs", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], + hdf: [ + "android.whichdoc online", + "android.hasSamples true", + ], + proofread_file: "online-sdk-dev-docs-proofread.txt", + args: framework_docs_only_args + + " -toroot / -samplegroup Admin " + + " -samplegroup Background " + + " -samplegroup Connectivity " + + " -samplegroup Content " + + " -samplegroup Input " + + " -samplegroup Media " + + " -samplegroup Notification " + + " -samplegroup RenderScript " + + " -samplegroup Security " + + " -samplegroup Sensors " + + " -samplegroup System " + + " -samplegroup Testing " + + " -samplegroup UI " + + " -samplegroup Views " + + " -samplegroup Wearable -samplesdir development/samples/browseable ", +} + +droiddoc { + name: "hidden-docs", + defaults: ["framework-docs-default"], + srcs: [ + ":framework-doc-stubs", + ], + proofread_file: "hidden-docs-proofread.txt", + args: framework_docs_only_args + + " -referenceonly " + + " -title \"Android SDK - Including hidden APIs.\"", +} diff --git a/api/OWNERS b/api/OWNERS index 4d8ed0347f43..bf6216c168e8 100644 --- a/api/OWNERS +++ b/api/OWNERS @@ -3,7 +3,7 @@ hansson@google.com # Modularization team file:platform/packages/modules/common:/OWNERS -per-file Android.bp = file:platform/build/soong:/OWNERS +per-file Android.bp = file:platform/build/soong:/OWNERS #{LAST_RESORT_SUGGESTION} # For metalava team to disable lint checks in platform -per-file Android.bp = aurimas@google.com,emberrose@google.com,sjgilbert@google.com
\ No newline at end of file +per-file Android.bp = aurimas@google.com,emberrose@google.com,sjgilbert@google.com diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp new file mode 100644 index 000000000000..f08745b5cd2c --- /dev/null +++ b/api/StubLibraries.bp @@ -0,0 +1,600 @@ +// 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. + +// How stubs are generated: +// +// raw source files --(metalava)--> stub source files --(javac)--> stub jar files +// +// - The metalava conversion is done by droidstub modules +// - The javac compilation is done by java_library modules +// +// The metalava conversion is also responsible for creating API signature files +// and comparing them against the checked in API signature, and also checking compatibility +// with the latest frozen API signature. + +///////////////////////////////////////////////////////////////////// +// These modules provide source files for the stub libraries +///////////////////////////////////////////////////////////////////// + +droidstubs { + name: "api-stubs-docs-non-updatable", + defaults: [ + "android-non-updatable-stubs-defaults", + "module-classpath-stubs-defaults", + ], + args: metalava_framework_docs_args, + check_api: { + current: { + api_file: ":non-updatable-current.txt", + removed_api_file: ":non-updatable-removed.txt", + }, + last_released: { + api_file: ":android-non-updatable.api.public.latest", + removed_api_file: ":android-non-updatable-removed.api.public.latest", + baseline_file: ":android-non-updatable-incompatibilities.api.public.latest", + }, + api_lint: { + enabled: true, + new_since: ":android.api.public.latest", + }, + }, + dists: [ + { + targets: ["sdk"], + dir: "apistubs/android/public/api", + dest: "android-non-updatable.txt", + tag: ".api.txt", + }, + { + targets: ["sdk"], + dir: "apistubs/android/public/api", + dest: "android-non-updatable-removed.txt", + tag: ".removed-api.txt", + }, + ], +} + +priv_apps = " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" + + "\\)" + +priv_apps_in_stubs = " --show-for-stub-purposes-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.PRIVILEGED_APPS" + + "\\)" + +test = " --show-annotation android.annotation.TestApi" + +module_libs = " --show-annotation android.annotation.SystemApi\\(" + + "client=android.annotation.SystemApi.Client.MODULE_LIBRARIES" + + "\\)" + +droidstubs { + name: "system-api-stubs-docs-non-updatable", + defaults: [ + "android-non-updatable-stubs-defaults", + "module-classpath-stubs-defaults", + ], + args: metalava_framework_docs_args + priv_apps, + check_api: { + current: { + api_file: ":non-updatable-system-current.txt", + removed_api_file: ":non-updatable-system-removed.txt", + }, + last_released: { + api_file: ":android-non-updatable.api.system.latest", + removed_api_file: ":android-non-updatable-removed.api.system.latest", + baseline_file: ":android-non-updatable-incompatibilities.api.system.latest", + }, + api_lint: { + enabled: true, + new_since: ":android.api.system.latest", + baseline_file: ":non-updatable-system-lint-baseline.txt", + }, + }, + dists: [ + { + targets: ["sdk"], + dir: "apistubs/android/system/api", + dest: "android-non-updatable.txt", + tag: ".api.txt", + }, + { + targets: ["sdk"], + dir: "apistubs/android/system/api", + dest: "android-non-updatable-removed.txt", + tag: ".removed-api.txt", + }, + ], +} + +droidstubs { + name: "test-api-stubs-docs-non-updatable", + defaults: [ + "android-non-updatable-stubs-defaults", + "module-classpath-stubs-defaults", + ], + args: metalava_framework_docs_args + test + priv_apps_in_stubs, + check_api: { + current: { + api_file: ":non-updatable-test-current.txt", + removed_api_file: ":non-updatable-test-removed.txt", + }, + api_lint: { + enabled: true, + baseline_file: ":non-updatable-test-lint-baseline.txt", + }, + }, + dists: [ + { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "android.txt", + tag: ".api.txt", + }, + { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "removed.txt", + tag: ".removed-api.txt", + }, + { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "android-non-updatable.txt", + tag: ".api.txt", + }, + { + targets: ["sdk"], + dir: "apistubs/android/test/api", + dest: "android-non-updatable-removed.txt", + tag: ".removed-api.txt", + }, + ], +} + +droidstubs { + name: "module-lib-api-stubs-docs-non-updatable", + defaults: [ + "android-non-updatable-stubs-defaults", + "module-classpath-stubs-defaults", + ], + args: metalava_framework_docs_args + priv_apps_in_stubs + module_libs, + check_api: { + current: { + api_file: ":non-updatable-module-lib-current.txt", + removed_api_file: ":non-updatable-module-lib-removed.txt", + }, + last_released: { + api_file: ":android-non-updatable.api.module-lib.latest", + removed_api_file: ":android-non-updatable-removed.api.module-lib.latest", + baseline_file: ":android-non-updatable-incompatibilities.api.module-lib.latest", + }, + api_lint: { + enabled: true, + new_since: ":android.api.module-lib.latest", + baseline_file: ":non-updatable-module-lib-lint-baseline.txt", + }, + }, + dists: [ + { + targets: ["sdk"], + dir: "apistubs/android/module-lib/api", + dest: "android-non-updatable.txt", + tag: ".api.txt", + }, + { + targets: ["sdk"], + dir: "apistubs/android/module-lib/api", + dest: "android-non-updatable-removed.txt", + tag: ".removed-api.txt", + }, + ], +} + +///////////////////////////////////////////////////////////////////// +// android_*_stubs_current modules are the stubs libraries compiled +// from stub sources +///////////////////////////////////////////////////////////////////// + +java_defaults { + name: "android.jar_defaults", + sdk_version: "none", + system_modules: "none", + java_version: "1.8", + compile_dex: true, + defaults_visibility: ["//visibility:private"], + visibility: ["//visibility:public"], +} + +java_defaults { + name: "android-non-updatable_defaults_stubs_current", + libs: ["stub-annotations"], + static_libs: ["framework-res-package-jar"], // Export package of framework-res + sdk_version: "none", + system_modules: "none", + java_version: "1.8", + compile_dex: true, + dist: { + targets: ["sdk"], + tag: ".jar", + dest: "android-non-updatable.jar", + }, + defaults_visibility: ["//visibility:private"], + visibility: ["//visibility:private"], +} + +java_library { + name: "android-non-updatable.stubs", + defaults: ["android-non-updatable_defaults_stubs_current"], + srcs: [":api-stubs-docs-non-updatable"], + libs: ["all-modules-public-stubs"], + dist: { + dir: "apistubs/android/public", + }, +} + +java_library { + name: "android-non-updatable.stubs.system", + defaults: ["android-non-updatable_defaults_stubs_current"], + srcs: [":system-api-stubs-docs-non-updatable"], + libs: ["all-modules-system-stubs"], + dist: { + dir: "apistubs/android/system", + }, +} + +java_library { + name: "android-non-updatable.stubs.module_lib", + defaults: ["android-non-updatable_defaults_stubs_current"], + srcs: [":module-lib-api-stubs-docs-non-updatable"], + libs: [ + "sdk_module-lib_current_framework-tethering", + "sdk_module-lib_current_framework-connectivity-t", + "sdk_public_current_framework-bluetooth", + // NOTE: The below can be removed once the prebuilt stub contains bluetooth. + "sdk_system_current_android", + // NOTE: The below can be removed once the prebuilt stub contains IKE. + "sdk_system_current_android.net.ipsec.ike", + ], + dist: { + dir: "apistubs/android/module-lib", + }, +} + +java_library { + name: "android-non-updatable.stubs.test", + defaults: ["android-non-updatable_defaults_stubs_current"], + srcs: [":test-api-stubs-docs-non-updatable"], + libs: ["all-modules-system-stubs"], + dist: { + dir: "apistubs/android/test", + }, +} + +java_defaults { + name: "android_stubs_dists_default", + dist: { + targets: ["sdk"], + tag: ".jar", + dest: "android.jar", + }, + defaults_visibility: ["//frameworks/base/services"], +} + +java_library { + name: "android_stubs_current", + static_libs: [ + "all-modules-public-stubs", + "android-non-updatable.stubs", + "private-stub-annotations-jar", + ], + defaults: ["android.jar_defaults"], +} + +java_library { + name: "android_system_stubs_current", + static_libs: [ + "all-modules-system-stubs", + "android-non-updatable.stubs.system", + "private-stub-annotations-jar", + ], + defaults: [ + "android.jar_defaults", + "android_stubs_dists_default", + ], + dist: { + dir: "apistubs/android/system", + }, + dists: [ + { + // Legacy dist path + targets: ["sdk"], + tag: ".jar", + dest: "android_system.jar", + }, + ], +} + +java_library { + name: "android_test_stubs_current", + static_libs: [ + // Updatable modules do not have test APIs, but we want to include their SystemApis, like we + // include the SystemApi of framework-non-updatable-sources. + "all-updatable-modules-system-stubs", + // Non-updatable modules on the other hand can have test APIs, so include their test-stubs. + "all-non-updatable-modules-test-stubs", + "android-non-updatable.stubs.test", + "private-stub-annotations-jar", + ], + defaults: [ + "android.jar_defaults", + "android_stubs_dists_default", + ], + dist: { + dir: "apistubs/android/test", + }, +} + +java_library { + name: "android_module_lib_stubs_current", + defaults: [ + "android.jar_defaults", + "android_stubs_dists_default", + ], + static_libs: [ + "android-non-updatable.stubs.module_lib", + "art.module.public.api.stubs.module_lib", + "i18n.module.public.api.stubs", + ], + dist: { + dir: "apistubs/android/module-lib", + }, +} + +java_library { + name: "android_system_server_stubs_current", + defaults: [ + "android.jar_defaults", + "android_stubs_dists_default", + ], + srcs: [":services-non-updatable-stubs"], + installable: false, + static_libs: [ + "android_module_lib_stubs_current", + ], + dist: { + dir: "apistubs/android/system-server", + }, +} + +java_library { + name: "android_stubs_private_jar", + defaults: ["android.jar_defaults"], + visibility: [ + "//visibility:override", + "//visibility:private", + ], + static_libs: [ + "stable.core.platform.api.stubs", + "core-lambda-stubs-for-system-modules", + "core-generated-annotation-stubs", + "framework", + "ext", + "framework-res-package-jar", + // The order of this matters, it has to be last to provide a + // package-private androidx.annotation.RecentlyNonNull without + // overriding the public android.annotation.Nullable in framework.jar + // with its own package-private android.annotation.Nullable. + "private-stub-annotations-jar", + ], +} + +java_genrule { + name: "android_stubs_private_hjar", + visibility: ["//visibility:private"], + srcs: [":android_stubs_private_jar{.hjar}"], + out: ["android_stubs_private.jar"], + cmd: "cp $(in) $(out)", +} + +java_library { + name: "android_stubs_private", + defaults: ["android_stubs_dists_default"], + visibility: ["//visibility:private"], + sdk_version: "none", + system_modules: "none", + static_libs: ["android_stubs_private_hjar"], + dist: { + dir: "apistubs/android/private", + }, +} + +java_genrule { + name: "android_stubs_private_framework_aidl", + visibility: ["//visibility:private"], + tools: ["sdkparcelables"], + srcs: [":android_stubs_private"], + out: ["framework.aidl"], + cmd: "rm -f $(genDir)/framework.aidl.merged && " + + "for i in $(in); do " + + " rm -f $(genDir)/framework.aidl.tmp && " + + " $(location sdkparcelables) $$i $(genDir)/framework.aidl.tmp && " + + " cat $(genDir)/framework.aidl.tmp >> $(genDir)/framework.aidl.merged; " + + "done && " + + "sort -u $(genDir)/framework.aidl.merged > $(out)", + dist: { + targets: ["sdk"], + dir: "apistubs/android/private", + }, +} + +//////////////////////////////////////////////////////////////////////// +// api-versions.xml generation, for public and system. This API database +// also contains the android.test.* APIs. +//////////////////////////////////////////////////////////////////////// + +java_library { + name: "android_stubs_current_with_test_libs", + static_libs: [ + "android_stubs_current", + "android.test.base.stubs", + "android.test.mock.stubs", + "android.test.runner.stubs", + ], + defaults: ["android.jar_defaults"], + visibility: [ + "//visibility:override", + "//visibility:private", + ], +} + +java_library { + name: "android_system_stubs_current_with_test_libs", + static_libs: [ + "android_system_stubs_current", + "android.test.base.stubs.system", + "android.test.mock.stubs.system", + "android.test.runner.stubs.system", + ], + defaults: ["android.jar_defaults"], + visibility: [ + "//visibility:override", + "//visibility:private", + ], +} + +java_library { + name: "android_module_stubs_current_with_test_libs", + static_libs: [ + "android_module_lib_stubs_current", + "android.test.base.stubs", + "android.test.mock.stubs", + "android.test.runner.stubs", + ], + defaults: ["android.jar_defaults"], + visibility: [ + "//visibility:override", + "//visibility:private", + ], +} + +java_library { + name: "android_system_server_stubs_current_with_test_libs", + static_libs: [ + "android_system_server_stubs_current", + "android.test.base.stubs.system", + "android.test.mock.stubs.system", + "android.test.runner.stubs.system", + ], + defaults: ["android.jar_defaults"], + visibility: [ + "//visibility:override", + "//visibility:private", + ], +} + +droidstubs { + name: "api_versions_public", + srcs: [":android_stubs_current_with_test_libs{.jar}"], + generate_stubs: false, + api_levels_annotations_enabled: true, + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", + ], + api_levels_sdk_type: "public", + extensions_info_file: ":sdk-extensions-info", + visibility: ["//frameworks/base"], +} + +droidstubs { + name: "api_versions_system", + srcs: [":android_system_stubs_current_with_test_libs{.jar}"], + generate_stubs: false, + api_levels_annotations_enabled: true, + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", + ], + api_levels_sdk_type: "system", + extensions_info_file: ":sdk-extensions-info", +} + +// This module can be built with: +// m out/soong/.intermediates/frameworks/base/api_versions_module_lib/android_common/metalava/api-versions.xml +droidstubs { + name: "api_versions_module_lib", + srcs: [":android_module_stubs_current_with_test_libs{.jar}"], + generate_stubs: false, + api_levels_annotations_enabled: true, + // this only has the non-updatable portions of the module lib sdk, + // which can reference classes from updatable apexes, so remove references to them + // from this api_versions file. + flags: ["--remove-missing-class-references-in-api-levels"], + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", + ], + api_levels_sdk_type: "module-lib", + // extensions_info_file is purposefully omitted, because this module should just be + // the non-updatable portions of the sdk, and extension sdks are updatable. +} + +droidstubs { + name: "api_versions_system_server", + srcs: [":android_system_server_stubs_current_with_test_libs{.jar}"], + generate_stubs: false, + api_levels_annotations_enabled: true, + // this only has the non-updatable portions of the system server sdk, + // which can reference classes from updatable apexes, so remove references to them + // from this api_versions file. + flags: ["--remove-missing-class-references-in-api-levels"], + api_levels_annotations_dirs: [ + "sdk-dir", + "api-versions-jars-dir", + ], + api_levels_sdk_type: "system-server", + // extensions_info_file is purposefully omitted, because this module should just be + // the non-updatable portions of the sdk, and extension sdks are updatable. +} + +///////////////////////////////////////////////////////////////////// +// hwbinder.stubs provides APIs required for building HIDL Java +// libraries. +///////////////////////////////////////////////////////////////////// + +droidstubs { + name: "hwbinder-stubs-docs", + srcs: [":hwbinder-stubs-srcs"], + libs: ["framework-annotations-lib"], + installable: false, + sdk_version: "core_platform", + annotations_enabled: true, + previous_api: ":android.api.public.latest", + merge_annotations_dirs: [ + "metalava-manual", + ], + args: priv_apps, + visibility: ["//visibility:private"], +} + +java_library { + name: "hwbinder.stubs", + sdk_version: "core_current", + libs: ["framework-annotations-lib"], + srcs: [ + ":hwbinder-stubs-docs", + ], + visibility: ["//visibility:public"], +} diff --git a/api/api.go b/api/api.go index ce8cd1426661..09c238336a39 100644 --- a/api/api.go +++ b/api/api.go @@ -20,6 +20,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/bazel" "android/soong/genrule" "android/soong/java" ) @@ -27,9 +28,20 @@ import ( const art = "art.module.public.api" const conscrypt = "conscrypt.module.public.api" const i18n = "i18n.module.public.api" +const virtualization = "framework-virtualization" var core_libraries_modules = []string{art, conscrypt, i18n} +// List of modules that are not yet updatable, and hence they can still compile +// against hidden APIs. These modules are filtered out when building the +// updatable-framework-module-impl (because updatable-framework-module-impl is +// built against module_current SDK). Instead they are directly statically +// linked into the all-framework-module-lib, which is building against hidden +// APIs. +// In addition, the modules in this list are allowed to contribute to test APIs +// stubs. +var non_updatable_modules = []string{virtualization} + // The intention behind this soong plugin is to generate a number of "merged" // API-related modules that would otherwise require a large amount of very // similar Android.bp boilerplate to define. For example, the merged current.txt @@ -49,6 +61,7 @@ type CombinedApisProperties struct { type CombinedApis struct { android.ModuleBase + android.BazelModuleBase properties CombinedApisProperties } @@ -89,6 +102,19 @@ type fgProps struct { Visibility []string } +type Bazel_module struct { + Bp2build_available *bool +} +type bazelProperties struct { + *Bazel_module +} + +var bp2buildNotAvailable = bazelProperties{ + &Bazel_module{ + Bp2build_available: proptools.BoolPtr(false), + }, +} + // Struct to pass parameters for the various merged [current|removed].txt file modules we create. type MergedTxtDefinition struct { // "current.txt" or "removed.txt" @@ -134,54 +160,38 @@ func createMergedTxt(ctx android.LoadHookContext, txt MergedTxtDefinition) { }, } props.Visibility = []string{"//visibility:public"} - ctx.CreateModule(genrule.GenRuleFactory, &props) -} - -func createMergedStubsSrcjar(ctx android.LoadHookContext, modules []string) { - props := genruleProps{} - props.Name = proptools.StringPtr(ctx.ModuleName() + "-current.srcjar") - props.Tools = []string{"merge_zips"} - props.Out = []string{"current.srcjar"} - props.Cmd = proptools.StringPtr("$(location merge_zips) $(out) $(in)") - props.Srcs = append([]string{":api-stubs-docs-non-updatable"}, createSrcs(modules, "{.public.stubs.source}")...) - props.Visibility = []string{"//visibility:private"} // Used by make module in //development, mind - ctx.CreateModule(genrule.GenRuleFactory, &props) -} - -// This produces the same annotations.zip as framework-doc-stubs, but by using -// outputs from individual modules instead of all the source code. -func createMergedAnnotations(ctx android.LoadHookContext, modules []string) { - props := genruleProps{} - props.Name = proptools.StringPtr("sdk-annotations.zip") - props.Tools = []string{"merge_annotation_zips", "soong_zip"} - props.Out = []string{"annotations.zip"} - props.Cmd = proptools.StringPtr("$(location merge_annotation_zips) $(genDir)/out $(in) && " + - "$(location soong_zip) -o $(out) -C $(genDir)/out -D $(genDir)/out") - props.Srcs = append([]string{":android-non-updatable-doc-stubs{.annotations.zip}"}, createSrcs(modules, "{.public.annotations.zip}")...) - ctx.CreateModule(genrule.GenRuleFactory, &props) + ctx.CreateModule(genrule.GenRuleFactory, &props, &bp2buildNotAvailable) } -func createFilteredApiVersions(ctx android.LoadHookContext, modules []string) { - // For the filtered api versions, we prune all APIs except art module's APIs. because - // 1) ART apis are available by default to all modules, while other module-to-module deps are - // explicit and probably receive more scrutiny anyway - // 2) The number of ART/libcore APIs is large, so not linting them would create a large gap - // 3) It's a compromise. Ideally we wouldn't be filtering out any module APIs, and have - // per-module lint databases that excludes just that module's APIs. Alas, that's more - // difficult to achieve. - modules = remove(modules, art) - - props := genruleProps{} - props.Name = proptools.StringPtr("api-versions-xml-public-filtered") - props.Tools = []string{"api_versions_trimmer"} - props.Out = []string{"api-versions-public-filtered.xml"} - props.Cmd = proptools.StringPtr("$(location api_versions_trimmer) $(out) $(in)") - // Note: order matters: first parameter is the full api-versions.xml - // after that the stubs files in any order - // stubs files are all modules that export API surfaces EXCEPT ART - props.Srcs = append([]string{":framework-doc-stubs{.api_versions.xml}"}, createSrcs(modules, ".stubs{.jar}")...) - props.Dists = []android.Dist{{Targets: []string{"sdk"}}} - ctx.CreateModule(genrule.GenRuleFactory, &props) +func createMergedAnnotationsFilegroups(ctx android.LoadHookContext, modules, system_server_modules []string) { + for _, i := range []struct{ + name string + tag string + modules []string + }{ + { + name: "all-modules-public-annotations", + tag: "{.public.annotations.zip}", + modules: modules, + }, { + name: "all-modules-system-annotations", + tag: "{.system.annotations.zip}", + modules: modules, + }, { + name: "all-modules-module-lib-annotations", + tag: "{.module-lib.annotations.zip}", + modules: modules, + }, { + name: "all-modules-system-server-annotations", + tag: "{.system-server.annotations.zip}", + modules: system_server_modules, + }, + } { + props := fgProps{} + props.Name = proptools.StringPtr(i.name) + props.Srcs = createSrcs(i.modules, i.tag) + ctx.CreateModule(android.FileGroupFactory, &props, &bp2buildNotAvailable) + } } func createMergedPublicStubs(ctx android.LoadHookContext, modules []string) { @@ -194,9 +204,33 @@ func createMergedPublicStubs(ctx android.LoadHookContext, modules []string) { } func createMergedSystemStubs(ctx android.LoadHookContext, modules []string) { + // First create the all-updatable-modules-system-stubs + { + updatable_modules := removeAll(modules, non_updatable_modules) + props := libraryProps{} + props.Name = proptools.StringPtr("all-updatable-modules-system-stubs") + props.Static_libs = transformArray(updatable_modules, "", ".stubs.system") + props.Sdk_version = proptools.StringPtr("module_current") + props.Visibility = []string{"//frameworks/base"} + ctx.CreateModule(java.LibraryFactory, &props) + } + // Now merge all-updatable-modules-system-stubs and stubs from non-updatable modules + // into all-modules-system-stubs. + { + props := libraryProps{} + props.Name = proptools.StringPtr("all-modules-system-stubs") + props.Static_libs = transformArray(non_updatable_modules, "", ".stubs.system") + props.Static_libs = append(props.Static_libs, "all-updatable-modules-system-stubs") + props.Sdk_version = proptools.StringPtr("module_current") + props.Visibility = []string{"//frameworks/base"} + ctx.CreateModule(java.LibraryFactory, &props) + } +} + +func createMergedTestStubsForNonUpdatableModules(ctx android.LoadHookContext) { props := libraryProps{} - props.Name = proptools.StringPtr("all-modules-system-stubs") - props.Static_libs = transformArray(modules, "", ".stubs.system") + props.Name = proptools.StringPtr("all-non-updatable-modules-test-stubs") + props.Static_libs = transformArray(non_updatable_modules, "", ".stubs.test") props.Sdk_version = proptools.StringPtr("module_current") props.Visibility = []string{"//frameworks/base"} ctx.CreateModule(java.LibraryFactory, &props) @@ -205,12 +239,31 @@ func createMergedSystemStubs(ctx android.LoadHookContext, modules []string) { func createMergedFrameworkImpl(ctx android.LoadHookContext, modules []string) { // This module is for the "framework-all" module, which should not include the core libraries. modules = removeAll(modules, core_libraries_modules) - props := libraryProps{} - props.Name = proptools.StringPtr("all-framework-module-impl") - props.Static_libs = transformArray(modules, "", ".impl") - props.Sdk_version = proptools.StringPtr("module_current") - props.Visibility = []string{"//frameworks/base"} - ctx.CreateModule(java.LibraryFactory, &props) + // Remove the modules that belong to non-updatable APEXes since those are allowed to compile + // against unstable APIs. + modules = removeAll(modules, non_updatable_modules) + // First create updatable-framework-module-impl, which contains all updatable modules. + // This module compiles against module_lib SDK. + { + props := libraryProps{} + props.Name = proptools.StringPtr("updatable-framework-module-impl") + props.Static_libs = transformArray(modules, "", ".impl") + props.Sdk_version = proptools.StringPtr("module_current") + props.Visibility = []string{"//frameworks/base"} + ctx.CreateModule(java.LibraryFactory, &props) + } + + // Now create all-framework-module-impl, which contains updatable-framework-module-impl + // and all non-updatable modules. This module compiles against hidden APIs. + { + props := libraryProps{} + props.Name = proptools.StringPtr("all-framework-module-impl") + props.Static_libs = transformArray(non_updatable_modules, "", ".impl") + props.Static_libs = append(props.Static_libs, "updatable-framework-module-impl") + props.Sdk_version = proptools.StringPtr("core_platform") + props.Visibility = []string{"//frameworks/base"} + ctx.CreateModule(java.LibraryFactory, &props) + } } func createMergedFrameworkModuleLibStubs(ctx android.LoadHookContext, modules []string) { @@ -229,7 +282,7 @@ func createPublicStubsSourceFilegroup(ctx android.LoadHookContext, modules []str props.Name = proptools.StringPtr("all-modules-public-stubs-source") props.Srcs = createSrcs(modules, "{.public.stubs.source}") props.Visibility = []string{"//frameworks/base"} - ctx.CreateModule(android.FileGroupFactory, &props) + ctx.CreateModule(android.FileGroupFactory, &props, &bp2buildNotAvailable) } func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_classpath []string) { @@ -278,22 +331,20 @@ func createMergedTxts(ctx android.LoadHookContext, bootclasspath, system_server_ func (a *CombinedApis) createInternalModules(ctx android.LoadHookContext) { bootclasspath := a.properties.Bootclasspath + system_server_classpath := a.properties.System_server_classpath if ctx.Config().VendorConfig("ANDROID").Bool("include_nonpublic_framework_api") { bootclasspath = append(bootclasspath, a.properties.Conditional_bootclasspath...) sort.Strings(bootclasspath) } - createMergedTxts(ctx, bootclasspath, a.properties.System_server_classpath) - - createMergedStubsSrcjar(ctx, bootclasspath) + createMergedTxts(ctx, bootclasspath, system_server_classpath) createMergedPublicStubs(ctx, bootclasspath) createMergedSystemStubs(ctx, bootclasspath) + createMergedTestStubsForNonUpdatableModules(ctx) createMergedFrameworkModuleLibStubs(ctx, bootclasspath) createMergedFrameworkImpl(ctx, bootclasspath) - createMergedAnnotations(ctx, bootclasspath) - - createFilteredApiVersions(ctx, bootclasspath) + createMergedAnnotationsFilegroups(ctx, bootclasspath, system_server_classpath) createPublicStubsSourceFilegroup(ctx, bootclasspath) } @@ -303,9 +354,55 @@ func combinedApisModuleFactory() android.Module { module.AddProperties(&module.properties) android.InitAndroidModule(module) android.AddLoadHook(module, func(ctx android.LoadHookContext) { module.createInternalModules(ctx) }) + android.InitBazelModule(module) return module } +type bazelCombinedApisAttributes struct { + Scope bazel.StringAttribute + Base bazel.LabelAttribute + Deps bazel.LabelListAttribute +} + +// combined_apis bp2build converter +func (a *CombinedApis) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + basePrefix := "non-updatable" + scopeToSuffix := map[string]string{ + "public": "-current.txt", + "system": "-system-current.txt", + "module-lib": "-module-lib-current.txt", + "system-server": "-system-server-current.txt", + } + + for scopeName, suffix := range scopeToSuffix{ + name := a.Name() + suffix + + var scope bazel.StringAttribute + scope.SetValue(scopeName) + + var base bazel.LabelAttribute + base.SetValue(android.BazelLabelForModuleDepSingle(ctx, basePrefix+suffix)) + + var deps bazel.LabelListAttribute + classpath := a.properties.Bootclasspath + if scopeName == "system-server" { + classpath = a.properties.System_server_classpath + } + deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, classpath)) + + attrs := bazelCombinedApisAttributes{ + Scope: scope, + Base: base, + Deps: deps, + } + props := bazel.BazelTargetModuleProperties{ + Rule_class: "merged_txts", + Bzl_load_location: "//build/bazel/rules/java:merged_txts.bzl", + } + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, &attrs) + } +} + // Various utility methods below. // Creates an array of ":<m><tag>" for each m in <modules>. diff --git a/api/api_test.go b/api/api_test.go new file mode 100644 index 000000000000..15b695ca0d36 --- /dev/null +++ b/api/api_test.go @@ -0,0 +1,68 @@ +// Copyright (C) 2023 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT 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 api + +import ( + "testing" + + "android/soong/android" + "android/soong/bp2build" +) + +func runCombinedApisTestCaseWithRegistrationCtxFunc(t *testing.T, tc bp2build.Bp2buildTestCase, registrationCtxFunc func(ctx android.RegistrationContext)) { + t.Helper() + (&tc).ModuleTypeUnderTest = "combined_apis" + (&tc).ModuleTypeUnderTestFactory = combinedApisModuleFactory + bp2build.RunBp2BuildTestCase(t, registrationCtxFunc, tc) +} + +func runCombinedApisTestCase(t *testing.T, tc bp2build.Bp2buildTestCase) { + t.Helper() + runCombinedApisTestCaseWithRegistrationCtxFunc(t, tc, func(ctx android.RegistrationContext) {}) +} + +func TestCombinedApisGeneral(t *testing.T) { + runCombinedApisTestCase(t, bp2build.Bp2buildTestCase{ + Description: "combined_apis, general case", + Blueprint: `combined_apis { + name: "foo", + bootclasspath: ["bcp"], + system_server_classpath: ["ssc"], +} +`, + ExpectedBazelTargets: []string{ + bp2build.MakeBazelTargetNoRestrictions("merged_txts", "foo-current.txt", bp2build.AttrNameToString{ + "scope": `"public"`, + "base": `":non-updatable-current.txt__BP2BUILD__MISSING__DEP"`, + "deps": `[":bcp__BP2BUILD__MISSING__DEP"]`, + }), + bp2build.MakeBazelTargetNoRestrictions("merged_txts", "foo-system-current.txt", bp2build.AttrNameToString{ + "scope": `"system"`, + "base": `":non-updatable-system-current.txt__BP2BUILD__MISSING__DEP"`, + "deps": `[":bcp__BP2BUILD__MISSING__DEP"]`, + }), + bp2build.MakeBazelTargetNoRestrictions("merged_txts", "foo-module-lib-current.txt", bp2build.AttrNameToString{ + "scope": `"module-lib"`, + "base": `":non-updatable-module-lib-current.txt__BP2BUILD__MISSING__DEP"`, + "deps": `[":bcp__BP2BUILD__MISSING__DEP"]`, + }), + bp2build.MakeBazelTargetNoRestrictions("merged_txts", "foo-system-server-current.txt", bp2build.AttrNameToString{ + "scope": `"system-server"`, + "base": `":non-updatable-system-server-current.txt__BP2BUILD__MISSING__DEP"`, + "deps": `[":ssc__BP2BUILD__MISSING__DEP"]`, + }), + }, + }) +} diff --git a/api/api_versions_trimmer.py b/api/api_versions_trimmer.py deleted file mode 100755 index 9afd95a3003a..000000000000 --- a/api/api_versions_trimmer.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2021 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Script to remove mainline APIs from the api-versions.xml.""" - -import argparse -import re -import xml.etree.ElementTree as ET -import zipfile - - -def read_classes(stubs): - """Read classes from the stubs file. - - Args: - stubs: argument can be a path to a file (a string), a file-like object or a - path-like object - - Returns: - a set of the classes found in the file (set of strings) - """ - classes = set() - with zipfile.ZipFile(stubs) as z: - for info in z.infolist(): - if (not info.is_dir() - and info.filename.endswith(".class") - and not info.filename.startswith("META-INF")): - # drop ".class" extension - classes.add(info.filename[:-6]) - return classes - - -def filter_method_tag(method, classes_to_remove): - """Updates the signature of this method by calling filter_method_signature. - - Updates the method passed into this function. - - Args: - method: xml element that represents a method - classes_to_remove: set of classes you to remove - """ - filtered = filter_method_signature(method.get("name"), classes_to_remove) - method.set("name", filtered) - - -def filter_method_signature(signature, classes_to_remove): - """Removes mentions of certain classes from this method signature. - - Replaces any existing classes that need to be removed, with java/lang/Object - - Args: - signature: string that is a java representation of a method signature - classes_to_remove: set of classes you to remove - """ - regex = re.compile("L.*?;") - start = signature.find("(") - matches = set(regex.findall(signature[start:])) - for m in matches: - # m[1:-1] to drop the leading `L` and `;` ending - if m[1:-1] in classes_to_remove: - signature = signature.replace(m, "Ljava/lang/Object;") - return signature - - -def filter_lint_database(database, classes_to_remove, output): - """Reads a lint database and writes a filtered version without some classes. - - Reads database from api-versions.xml and removes any references to classes - in the second argument. Writes the result (another xml with the same format - of the database) to output. - - Args: - database: path to xml with lint database to read - classes_to_remove: iterable (ideally a set or similar for quick - lookups) that enumerates the classes that should be removed - output: path to write the filtered database - """ - xml = ET.parse(database) - root = xml.getroot() - for c in xml.findall("class"): - cname = c.get("name") - if cname in classes_to_remove: - root.remove(c) - else: - # find the <extends /> tag inside this class to see if the parent - # has been removed from the known classes (attribute called name) - super_classes = c.findall("extends") - for super_class in super_classes: - super_class_name = super_class.get("name") - if super_class_name in classes_to_remove: - super_class.set("name", "java/lang/Object") - interfaces = c.findall("implements") - for interface in interfaces: - interface_name = interface.get("name") - if interface_name in classes_to_remove: - c.remove(interface) - for method in c.findall("method"): - filter_method_tag(method, classes_to_remove) - xml.write(output) - - -def main(): - """Run the program.""" - parser = argparse.ArgumentParser( - description= - ("Read a lint database (api-versions.xml) and many stubs jar files. " - "Produce another database file that doesn't include the classes present " - "in the stubs file(s).")) - parser.add_argument("output", help="Destination of the result (xml file).") - parser.add_argument( - "api_versions", - help="The lint database (api-versions.xml file) to read data from" - ) - parser.add_argument("stubs", nargs="+", help="The stubs jar file(s)") - parsed = parser.parse_args() - classes = set() - for stub in parsed.stubs: - classes.update(read_classes(stub)) - filter_lint_database(parsed.api_versions, classes, parsed.output) - - -if __name__ == "__main__": - main() diff --git a/api/api_versions_trimmer_unittests.py b/api/api_versions_trimmer_unittests.py deleted file mode 100644 index d2e5b7d1a07e..000000000000 --- a/api/api_versions_trimmer_unittests.py +++ /dev/null @@ -1,307 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2021 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import io -import re -import unittest -import xml.etree.ElementTree as ET -import zipfile - -import api_versions_trimmer - - -def create_in_memory_zip_file(files): - f = io.BytesIO() - with zipfile.ZipFile(f, "w") as z: - for fname in files: - with z.open(fname, mode="w") as class_file: - class_file.write(b"") - return f - - -def indent(elem, level=0): - i = "\n" + level * " " - j = "\n" + (level - 1) * " " - if len(elem): - if not elem.text or not elem.text.strip(): - elem.text = i + " " - if not elem.tail or not elem.tail.strip(): - elem.tail = i - for subelem in elem: - indent(subelem, level + 1) - if not elem.tail or not elem.tail.strip(): - elem.tail = j - else: - if level and (not elem.tail or not elem.tail.strip()): - elem.tail = j - return elem - - -def pretty_print(s): - tree = ET.parse(io.StringIO(s)) - el = indent(tree.getroot()) - res = ET.tostring(el).decode("utf-8") - # remove empty lines inside the result because this still breaks some - # comparisons - return re.sub(r"\n\s*\n", "\n", res, re.MULTILINE) - - -class ApiVersionsTrimmerUnittests(unittest.TestCase): - - def setUp(self): - # so it prints diffs in long strings (xml files) - self.maxDiff = None - - def test_read_classes(self): - f = create_in_memory_zip_file( - ["a/b/C.class", - "a/b/D.class", - ] - ) - res = api_versions_trimmer.read_classes(f) - self.assertEqual({"a/b/C", "a/b/D"}, res) - - def test_read_classes_ignore_dex(self): - f = create_in_memory_zip_file( - ["a/b/C.class", - "a/b/D.class", - "a/b/E.dex", - "f.dex", - ] - ) - res = api_versions_trimmer.read_classes(f) - self.assertEqual({"a/b/C", "a/b/D"}, res) - - def test_read_classes_ignore_manifest(self): - f = create_in_memory_zip_file( - ["a/b/C.class", - "a/b/D.class", - "META-INFO/G.class" - ] - ) - res = api_versions_trimmer.read_classes(f) - self.assertEqual({"a/b/C", "a/b/D"}, res) - - def test_filter_method_signature(self): - xml = """ - <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/> - """ - method = ET.fromstring(xml) - classes_to_remove = {"android/accessibilityservice/GestureDescription"} - expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" - api_versions_trimmer.filter_method_tag(method, classes_to_remove) - self.assertEqual(expected, method.get("name")) - - def test_filter_method_signature_with_L_in_method(self): - xml = """ - <method name="dispatchLeftGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/> - """ - method = ET.fromstring(xml) - classes_to_remove = {"android/accessibilityservice/GestureDescription"} - expected = "dispatchLeftGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" - api_versions_trimmer.filter_method_tag(method, classes_to_remove) - self.assertEqual(expected, method.get("name")) - - def test_filter_method_signature_with_L_in_class(self): - xml = """ - <method name="dispatchGesture(Landroid/accessibilityservice/LeftGestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/> - """ - method = ET.fromstring(xml) - classes_to_remove = {"android/accessibilityservice/LeftGestureDescription"} - expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" - api_versions_trimmer.filter_method_tag(method, classes_to_remove) - self.assertEqual(expected, method.get("name")) - - def test_filter_method_signature_with_inner_class(self): - xml = """ - <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription$Inner;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/> - """ - method = ET.fromstring(xml) - classes_to_remove = {"android/accessibilityservice/GestureDescription$Inner"} - expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" - api_versions_trimmer.filter_method_tag(method, classes_to_remove) - self.assertEqual(expected, method.get("name")) - - def _run_filter_db_test(self, database_str, expected): - """Performs the pattern of testing the filter_lint_database method. - - Filters instances of the class "a/b/C" (hard-coded) from the database string - and compares the result with the expected result (performs formatting of - the xml of both inputs) - - Args: - database_str: string, the contents of the lint database (api-versions.xml) - expected: string, the expected result after filtering the original - database - """ - database = io.StringIO(database_str) - classes_to_remove = {"a/b/C"} - output = io.BytesIO() - api_versions_trimmer.filter_lint_database( - database, - classes_to_remove, - output - ) - expected = pretty_print(expected) - res = pretty_print(output.getvalue().decode("utf-8")) - self.assertEqual(expected, res) - - def test_filter_lint_database_updates_method_signature_params(self): - self._run_filter_db_test( - database_str=""" - <api version="2"> - <!-- will be removed --> - <class name="a/b/C" since="1"> - <extends name="java/lang/Object"/> - </class> - - <class name="a/b/E" since="1"> - <!-- extends will be modified --> - <extends name="a/b/C"/> - <!-- first parameter will be modified --> - <method name="dispatchGesture(La/b/C;Landroid/os/Handler;)Z" since="24"/> - <!-- second should remain untouched --> - <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe -sultCallback;Landroid/os/Handler;)Z" since="24"/> - </class> - </api> - """, - expected=""" - <api version="2"> - <class name="a/b/E" since="1"> - <extends name="java/lang/Object"/> - <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/> - <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe -sultCallback;Landroid/os/Handler;)Z" since="24"/> - </class> - </api> - """) - - def test_filter_lint_database_updates_method_signature_return(self): - self._run_filter_db_test( - database_str=""" - <api version="2"> - <!-- will be removed --> - <class name="a/b/C" since="1"> - <extends name="java/lang/Object"/> - </class> - - <class name="a/b/E" since="1"> - <!-- extends will be modified --> - <extends name="a/b/C"/> - <!-- return type should be changed --> - <method name="gestureIdToString(I)La/b/C;" since="24"/> - </class> - </api> - """, - expected=""" - <api version="2"> - <class name="a/b/E" since="1"> - - <extends name="java/lang/Object"/> - - <method name="gestureIdToString(I)Ljava/lang/Object;" since="24"/> - </class> - </api> - """) - - def test_filter_lint_database_removes_implements(self): - self._run_filter_db_test( - database_str=""" - <api version="2"> - <!-- will be removed --> - <class name="a/b/C" since="1"> - <extends name="java/lang/Object"/> - </class> - - <class name="a/b/D" since="1"> - <extends name="java/lang/Object"/> - <implements name="a/b/C"/> - <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe -sultCallback;Landroid/os/Handler;)Z" since="24"/> - </class> - </api> - """, - expected=""" - <api version="2"> - - <class name="a/b/D" since="1"> - <extends name="java/lang/Object"/> - <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe -sultCallback;Landroid/os/Handler;)Z" since="24"/> - </class> - </api> - """) - - def test_filter_lint_database_updates_extends(self): - self._run_filter_db_test( - database_str=""" - <api version="2"> - <!-- will be removed --> - <class name="a/b/C" since="1"> - <extends name="java/lang/Object"/> - </class> - - <class name="a/b/E" since="1"> - <!-- extends will be modified --> - <extends name="a/b/C"/> - <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/> - <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe -sultCallback;Landroid/os/Handler;)Z" since="24"/> - </class> - </api> - """, - expected=""" - <api version="2"> - <class name="a/b/E" since="1"> - <extends name="java/lang/Object"/> - <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/> - <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe -sultCallback;Landroid/os/Handler;)Z" since="24"/> - </class> - </api> - """) - - def test_filter_lint_database_removes_class(self): - self._run_filter_db_test( - database_str=""" - <api version="2"> - <!-- will be removed --> - <class name="a/b/C" since="1"> - <extends name="java/lang/Object"/> - </class> - - <class name="a/b/D" since="1"> - <extends name="java/lang/Object"/> - <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe -sultCallback;Landroid/os/Handler;)Z" since="24"/> - </class> - </api> - """, - expected=""" - <api version="2"> - - <class name="a/b/D" since="1"> - <extends name="java/lang/Object"/> - <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe -sultCallback;Landroid/os/Handler;)Z" since="24"/> - </class> - </api> - """) - - -if __name__ == "__main__": - unittest.main(verbosity=2) diff --git a/api/docs b/api/docs new file mode 120000 index 000000000000..a9594bfe4ab6 --- /dev/null +++ b/api/docs @@ -0,0 +1 @@ +../docs
\ No newline at end of file |