diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-28 16:05:29 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-28 16:05:29 +0000 |
commit | 38249b4e903fad5400e61295941cfc2f2022183f (patch) | |
tree | 9ea8179b6c2a8553652bd80720ed7a572ee622c8 | |
parent | a74779fb99418bcfdf7c578b4b7fc60a86c16ee5 (diff) | |
parent | 9ea376ddb288d03225157e538fd4e574fa973947 (diff) | |
download | common-38249b4e903fad5400e61295941cfc2f2022183f.tar.gz |
Snap for 8512216 from 9ea376ddb288d03225157e538fd4e574fa973947 to tm-frc-os-statsd-release
Change-Id: I312621b78da361bedfe9d54824bb0b8c21c8de44
-rw-r--r-- | Android.bp | 11 | ||||
-rw-r--r-- | OWNERS | 3 | ||||
-rw-r--r-- | build/allowed_deps.txt | 121 | ||||
-rwxr-xr-x | build/build_unbundled_mainline_module.sh | 1 | ||||
-rwxr-xr-x | build/mainline_modules_sdks.py | 581 | ||||
-rwxr-xr-x | build/mainline_modules_sdks.sh | 10 | ||||
-rw-r--r-- | build/mainline_modules_sdks_test.py | 442 | ||||
-rw-r--r-- | build/mainline_modules_sdks_test_data/art_Android.bp.expected | 6 | ||||
-rw-r--r-- | build/mainline_modules_sdks_test_data/google_wifi_for_r_Android.bp | 46 | ||||
-rw-r--r-- | build/mainline_modules_sdks_test_data/ipsec_Android.bp.expected | 4 | ||||
-rw-r--r-- | build/mainline_modules_sdks_test_data/ipsec_for_r_Android.bp | 46 | ||||
-rw-r--r-- | javatests/com/android/modules/updatablesharedlibs/Android.bp | 7 | ||||
-rw-r--r-- | javatests/com/android/modules/updatablesharedlibs/UpdatableSharedLibsTest.java | 8 | ||||
-rw-r--r-- | proto/sdk.proto | 5 | ||||
-rw-r--r-- | sdk/Android.bp | 1 | ||||
-rw-r--r-- | sdk/ModuleDefaults.bp | 35 | ||||
-rw-r--r-- | sdk/StubLibraries.bp | 61 | ||||
-rw-r--r-- | tools/Android.bp | 3 | ||||
-rwxr-xr-x | tools/finalize_sdk.py | 85 |
19 files changed, 1178 insertions, 298 deletions
@@ -80,6 +80,17 @@ soong_config_module_type { "prefer", ], } + +soong_config_module_type { + name: "module_java_test_import", + module_type: "java_test_import", + config_namespace: "ANDROID", + bool_variables: ["module_build_from_source"], + properties: [ + "prefer", + ], +} + soong_config_module_type { name: "module_java_sdk_library_import", module_type: "java_sdk_library_import", @@ -2,8 +2,9 @@ andreionea@google.com dariofreni@google.com +gurpreetgs@google.com hansson@google.com -mathewi@google.com +paulduffin@google.com pedroql@google.com satayev@google.com diff --git a/build/allowed_deps.txt b/build/allowed_deps.txt index 0655beec..5976406f 100644 --- a/build/allowed_deps.txt +++ b/build/allowed_deps.txt @@ -13,11 +13,20 @@ # See go/apex-allowed-deps-error for more details. # TODO(b/157465465): introduce automated quality signals and remove this list. +android.hardware.audio.common-V1-ndk(minSdkVersion:31) +android.hardware.audio.common@5.0(minSdkVersion:30) +android.hardware.bluetooth.a2dp@1.0(minSdkVersion:30) +android.hardware.bluetooth.audio-V1-ndk(minSdkVersion:31) +android.hardware.bluetooth.audio@2.0(minSdkVersion:30) +android.hardware.bluetooth.audio@2.1(minSdkVersion:30) +android.hardware.bluetooth@1.0(minSdkVersion:30) +android.hardware.bluetooth@1.1(minSdkVersion:30) android.hardware.cas.native@1.0(minSdkVersion:29) android.hardware.cas@1.0(minSdkVersion:29) android.hardware.common-ndk_platform(minSdkVersion:29) android.hardware.common-V2-ndk(minSdkVersion:29) android.hardware.common-V2-ndk_platform(minSdkVersion:29) +android.hardware.common.fmq-V1-ndk(minSdkVersion:29) android.hardware.graphics.allocator-V1-ndk(minSdkVersion:29) android.hardware.graphics.allocator@2.0(minSdkVersion:29) android.hardware.graphics.allocator@3.0(minSdkVersion:29) @@ -50,6 +59,7 @@ android.hardware.neuralnetworks@1.0(minSdkVersion:30) android.hardware.neuralnetworks@1.1(minSdkVersion:30) android.hardware.neuralnetworks@1.2(minSdkVersion:30) android.hardware.neuralnetworks@1.3(minSdkVersion:30) +android.hardware.radio-V1.0-java(minSdkVersion:current) android.hardware.tetheroffload.config-V1.0-java(minSdkVersion:current) android.hardware.tetheroffload.control-V1.0-java(minSdkVersion:current) android.hardware.tetheroffload.control-V1.1-java(minSdkVersion:current) @@ -85,9 +95,11 @@ android.hidl.safe_union@1.0(minSdkVersion:29) android.hidl.token@1.0(minSdkVersion:29) android.hidl.token@1.0-utils(minSdkVersion:29) android.media.audio.common.types-V1-cpp(minSdkVersion:29) +android.media.audio.common.types-V1-ndk(minSdkVersion:29) android.net.ipsec.ike.xml(minSdkVersion:(no version)) android.system.suspend-V1-ndk(minSdkVersion:30) android.system.suspend-V1-ndk(minSdkVersion:Tiramisu) +android.system.suspend.control-V1-ndk(minSdkVersion:30) android_downloader_lib(minSdkVersion:30) androidx-constraintlayout_constraintlayout(minSdkVersion:14) androidx-constraintlayout_constraintlayout-solver(minSdkVersion:24) @@ -120,6 +132,7 @@ androidx.fragment_fragment(minSdkVersion:14) androidx.fragment_fragment-ktx(minSdkVersion:14) androidx.interpolator_interpolator(minSdkVersion:14) androidx.leanback_leanback(minSdkVersion:17) +androidx.leanback_leanback-grid(minSdkVersion:17) androidx.leanback_leanback-preference(minSdkVersion:21) androidx.legacy_legacy-preference-v14(minSdkVersion:14) androidx.legacy_legacy-support-core-ui(minSdkVersion:14) @@ -181,6 +194,7 @@ audiopolicy-aidl-cpp(minSdkVersion:29) auto_value_annotations(minSdkVersion:19) av-headers(minSdkVersion:29) av-types-aidl-cpp(minSdkVersion:29) +avrcp_headers(minSdkVersion:30) bcm_object(minSdkVersion:29) bionic_libc_platform_headers(minSdkVersion:29) boringssl_self_test(minSdkVersion:29) @@ -195,9 +209,12 @@ car-rotary-lib(minSdkVersion:28) car-rotary-lib-resources(minSdkVersion:28) car-ui-lib(minSdkVersion:28) car-ui-lib-resources(minSdkVersion:28) +census(minSdkVersion:30) clatd(minSdkVersion:30) codecs_g711dec(minSdkVersion:29) +com.android.vcard(minSdkVersion:9) com.google.android.material_material(minSdkVersion:14) +connectivity_native_aidl_interface-V1-java(minSdkVersion:30) conscrypt(minSdkVersion:29) core-libart(minSdkVersion:31) core-oj(minSdkVersion:31) @@ -222,9 +239,9 @@ crtend_so(minSdkVersion:current) datastallprotosnano(minSdkVersion:29) dnsproxyd_protocol_headers(minSdkVersion:29) DocumentsUI-res-lib(minSdkVersion:29) -exoplayer2-annotation-stubs(minSdkVersion:16) -exoplayer2-extractor(minSdkVersion:16) -exoplayer2.15.1(minSdkVersion:16) +exoplayer-annotation_stubs(minSdkVersion:16) +exoplayer-mediaprovider-core(minSdkVersion:16) +exoplayer-mediaprovider-ui(minSdkVersion:16) ExtServices(minSdkVersion:30) ExtServices(minSdkVersion:current) ExtServices-core(minSdkVersion:30) @@ -234,6 +251,7 @@ fmtlib(minSdkVersion:29) fmtlib_headers(minSdkVersion:29) fmtlib_ndk(minSdkVersion:29) fp16_headers(minSdkVersion:30) +framework-bluetooth(minSdkVersion:current) framework-mediaprovider(minSdkVersion:30) framework-permission(minSdkVersion:30) framework-permission(minSdkVersion:current) @@ -249,10 +267,13 @@ GoogleCellBroadcastServiceModule(minSdkVersion:29) GoogleExtServices(minSdkVersion:30) GooglePermissionController(minSdkVersion:28) GooglePermissionController(minSdkVersion:30) +gpr_base(minSdkVersion:30) guava(minSdkVersion:current) gwp_asan_headers(minSdkVersion:S) +icing-java-proto-lite(minSdkVersion:current) iconloader(minSdkVersion:21) iconloader(minSdkVersion:26) +internal_include_headers(minSdkVersion:30) ipmemorystore-aidl-interfaces-java(minSdkVersion:29) ipmemorystore-aidl-interfaces-V10-java(minSdkVersion:29) jacocoagent(minSdkVersion:9) @@ -273,8 +294,11 @@ libadbd_core(minSdkVersion:(no version)) libadbd_core(minSdkVersion:30) libadbd_services(minSdkVersion:(no version)) libadbd_services(minSdkVersion:30) +libaddress_sorting(minSdkVersion:30) libaidlcommonsupport(minSdkVersion:29) liballoc.rust_sysroot(minSdkVersion:29) +libalts_frame_protector(minSdkVersion:30) +libalts_util(minSdkVersion:30) libamrextractor(minSdkVersion:29) libandroid_log_sys(minSdkVersion:29) libandroid_logger(minSdkVersion:29) @@ -286,6 +310,7 @@ libasync_safe(minSdkVersion:apex_inherit) libasyncio(minSdkVersion:(no version)) libasyncio(minSdkVersion:apex_inherit) libatomic(minSdkVersion:(no version)) +libaudio-a2dp-hw-utils(minSdkVersion:29) libaudio_system_headers(minSdkVersion:29) libaudioclient_aidl_conversion_util(minSdkVersion:29) libaudioclient_headers(minSdkVersion:29) @@ -310,8 +335,15 @@ libbinder_ndk_sys(minSdkVersion:Tiramisu) libbinder_rs(minSdkVersion:Tiramisu) libbinder_tokio_rs(minSdkVersion:Tiramisu) libbinderthreadstateutils(minSdkVersion:29) +libbitflags(minSdkVersion:29) +libbluetooth-types(minSdkVersion:29) libbluetooth-types-header(minSdkVersion:29) +libbluetooth_headers(minSdkVersion:30) libbrotli(minSdkVersion:(no version)) +libbt-platform-protos-lite(minSdkVersion:30) +libbt_keystore_cc(minSdkVersion:30) +libbt_keystore_cc_headers(minSdkVersion:30) +libbtcore_headers(minSdkVersion:30) libbuildversion(minSdkVersion:(no version)) libbuildversion(minSdkVersion:26) libbytes(minSdkVersion:29) @@ -328,6 +360,7 @@ libcap(minSdkVersion:29) libcesu8(minSdkVersion:29) libcfg_if(minSdkVersion:29) libcfg_if.rust_sysroot(minSdkVersion:29) +libchrome(minSdkVersion:30) libcodec2(minSdkVersion:29) libcodec2_headers(minSdkVersion:29) libcodec2_hidl@1.0(minSdkVersion:29) @@ -375,8 +408,11 @@ libcrypto_static(minSdkVersion:(no version)) libcrypto_utils(minSdkVersion:(no version)) libcrypto_utils(minSdkVersion:apex_inherit) libcutils(minSdkVersion:29) +libcutils_bindgen(minSdkVersion:29) libcutils_headers(minSdkVersion:29) libcutils_sockets(minSdkVersion:29) +libcxx(minSdkVersion:29) +libcxxbridge05(minSdkVersion:29) libdexfile_external_headers(minSdkVersion:31) libdexfile_support(minSdkVersion:31) libdiagnose_usb(minSdkVersion:(no version)) @@ -388,6 +424,7 @@ libdowncast_rs(minSdkVersion:29) libeigen(minSdkVersion:(no version)) libenv_logger(minSdkVersion:29) liberror_headers(minSdkVersion:29) +libevent(minSdkVersion:30) libexpat(minSdkVersion:apex_inherit) libexpectedutils_headers(minSdkVersion:29) libextservices(minSdkVersion:30) @@ -398,6 +435,7 @@ libFLAC(minSdkVersion:29) libFLAC-config(minSdkVersion:29) libFLAC-headers(minSdkVersion:29) libflacextractor(minSdkVersion:29) +libflatbuffers-cpp(minSdkVersion:30) libfmq(minSdkVersion:29) libfmq-base(minSdkVersion:29) libform_urlencoded(minSdkVersion:29) @@ -417,6 +455,41 @@ libgcc_stripped(minSdkVersion:(no version)) libgetopts(minSdkVersion:29) libgralloctypes(minSdkVersion:29) libgrallocusage(minSdkVersion:29) +libgrpc(minSdkVersion:30) +libgrpc++(minSdkVersion:30) +libgrpc++_base(minSdkVersion:30) +libgrpc++_codegen_base_src(minSdkVersion:30) +libgrpc_base(minSdkVersion:30) +libgrpc_base_c(minSdkVersion:30) +libgrpc_bindgen(minSdkVersion:29) +libgrpc_client_authority_filter(minSdkVersion:30) +libgrpc_client_channel(minSdkVersion:30) +libgrpc_deadline_filter(minSdkVersion:30) +libgrpc_http_filters(minSdkVersion:30) +libgrpc_lb_policy_grpclb_secure(minSdkVersion:30) +libgrpc_lb_policy_pick_first(minSdkVersion:30) +libgrpc_lb_policy_round_robin(minSdkVersion:30) +libgrpc_max_age_filter(minSdkVersion:30) +libgrpc_message_size_filter(minSdkVersion:30) +libgrpc_resolver_dns_ares(minSdkVersion:30) +libgrpc_resolver_dns_native(minSdkVersion:30) +libgrpc_resolver_fake(minSdkVersion:30) +libgrpc_resolver_sockaddr(minSdkVersion:30) +libgrpc_secure(minSdkVersion:30) +libgrpc_server_backward_compatibility(minSdkVersion:30) +libgrpc_trace(minSdkVersion:30) +libgrpc_transport_chttp2(minSdkVersion:30) +libgrpc_transport_chttp2_alpn(minSdkVersion:30) +libgrpc_transport_chttp2_client_connector(minSdkVersion:30) +libgrpc_transport_chttp2_client_insecure(minSdkVersion:30) +libgrpc_transport_chttp2_client_secure(minSdkVersion:30) +libgrpc_transport_chttp2_server_insecure(minSdkVersion:30) +libgrpc_transport_chttp2_server_secure(minSdkVersion:30) +libgrpc_transport_inproc(minSdkVersion:30) +libgrpc_workaround_cronet_compression_filter(minSdkVersion:30) +libgrpc_wrap(minSdkVersion:29) +libgrpcio(minSdkVersion:29) +libgrpcio_sys(minSdkVersion:29) libgsm(minSdkVersion:apex_inherit) libgtest_prod(minSdkVersion:apex_inherit) libgtest_prod_headers(minSdkVersion:apex_inherit) @@ -445,6 +518,8 @@ liblibc(minSdkVersion:29) liblibc.rust_sysroot(minSdkVersion:29) libLibGuiProperties(minSdkVersion:29) liblibm(minSdkVersion:29) +liblibz_sys(minSdkVersion:29) +liblock_api(minSdkVersion:29) liblog_headers(minSdkVersion:29) liblog_rust(minSdkVersion:29) liblogger(minSdkVersion:29) @@ -459,11 +534,13 @@ libmdnssd(minSdkVersion:(no version)) libmedia_codecserviceregistrant(minSdkVersion:29) libmedia_datasource_headers(minSdkVersion:29) libmedia_headers(minSdkVersion:29) +libmedia_helper(minSdkVersion:29) libmedia_helper_headers(minSdkVersion:29) libmedia_midiiowrapper(minSdkVersion:29) libmediaformatshaper(minSdkVersion:29) libmemchr(minSdkVersion:29) libmeminfo(minSdkVersion:S) +libmemoffset(minSdkVersion:29) libminijail(minSdkVersion:29) libminijail_gen_constants(minSdkVersion:(no version)) libminijail_gen_constants_obj(minSdkVersion:29) @@ -472,6 +549,7 @@ libminijail_gen_syscall_obj(minSdkVersion:29) libminijail_generated(minSdkVersion:29) libmio(minSdkVersion:29) libmkvextractor(minSdkVersion:29) +libmodpb64(minSdkVersion:30) libmp3extractor(minSdkVersion:29) libmp4extractor(minSdkVersion:29) libmpeg2dec(minSdkVersion:29) @@ -484,6 +562,7 @@ libnativehelper_header_only(minSdkVersion:29) libnativeloader-headers(minSdkVersion:31) libnativewindow_headers(minSdkVersion:29) libnet_utils_device_common_bpfjni(minSdkVersion:30) +libnet_utils_device_common_bpfutils(minSdkVersion:30) libnetdbinder_utils_headers(minSdkVersion:29) libnetdutils(minSdkVersion:29) libnetjniutils(minSdkVersion:29) @@ -491,6 +570,7 @@ libnetworkstackutilsjni(minSdkVersion:29) libneuralnetworks_common(minSdkVersion:(no version)) libneuralnetworks_headers(minSdkVersion:(no version)) libneuralnetworks_shim_static(minSdkVersion:30) +libnix(minSdkVersion:29) libnum_cpus(minSdkVersion:29) libnum_traits(minSdkVersion:29) liboggextractor(minSdkVersion:29) @@ -498,6 +578,8 @@ libonce_cell(minSdkVersion:29) libopenjdkjvmti_headers(minSdkVersion:31) libopus(minSdkVersion:29) libpanic_abort.rust_sysroot(minSdkVersion:29) +libparking_lot(minSdkVersion:29) +libparking_lot_core(minSdkVersion:29) libpercent_encoding(minSdkVersion:29) libperfetto_client_experimental(minSdkVersion:S) libpin_project_lite(minSdkVersion:29) @@ -515,8 +597,12 @@ libprofile-clang-extras_ndk(minSdkVersion:(no version)) libprofile-extras(minSdkVersion:(no version)) libprofile-extras_ndk(minSdkVersion:(no version)) libprofiler_builtins.rust_sysroot(minSdkVersion:29) +libprotobuf(minSdkVersion:29) +libprotobuf-c-nano(minSdkVersion:30) +libprotobuf-cpp-full(minSdkVersion:29) libprotobuf-cpp-lite(minSdkVersion:29) libprotobuf-java-lite(minSdkVersion:current) +libprotobuf-java-micro(minSdkVersion:8) libprotobuf-java-nano(minSdkVersion:9) libprotoutil(minSdkVersion:(no version)) libqemu_pipe(minSdkVersion:(no version)) @@ -527,9 +613,12 @@ libring-test(minSdkVersion:29) librustc_demangle(minSdkVersion:(no version)) librustc_demangle.rust_sysroot(minSdkVersion:29) librustc_demangle_static(minSdkVersion:(no version)) +librustutils(minSdkVersion:29) libruy_static(minSdkVersion:30) +libscopeguard(minSdkVersion:29) libsfplugin_ccodec_utils(minSdkVersion:29) libslab(minSdkVersion:29) +libsmallvec(minSdkVersion:29) libsonivoxwithoutjet(minSdkVersion:29) libspeexresampler(minSdkVersion:29) libspin(minSdkVersion:29) @@ -563,6 +652,7 @@ libstd(minSdkVersion:29) libstd_detect.rust_sysroot(minSdkVersion:29) libsync(minSdkVersion:(no version)) libsystem_headers(minSdkVersion:apex_inherit) +libsystem_properties_bindgen(minSdkVersion:29) libsysutils(minSdkVersion:apex_inherit) libtcutils(minSdkVersion:30) libterm(minSdkVersion:29) @@ -583,6 +673,9 @@ libtinyvec(minSdkVersion:29) libtinyvec_macros(minSdkVersion:29) libtinyxml2(minSdkVersion:S) libtokio(minSdkVersion:29) +libtokio_stream(minSdkVersion:29) +libtsi(minSdkVersion:30) +libtsi_interface(minSdkVersion:30) libui(minSdkVersion:29) libui-types(minSdkVersion:apex_inherit) libui_headers(minSdkVersion:29) @@ -595,8 +688,10 @@ libunwind_llvm(minSdkVersion:apex_inherit) libunwindstack(minSdkVersion:29) liburl(minSdkVersion:29) libutf(minSdkVersion:(no version)) +libutf(minSdkVersion:14) libutils(minSdkVersion:apex_inherit) libutils_headers(minSdkVersion:apex_inherit) +libuwb_uci_packets(minSdkVersion:Tiramisu) libvorbisidec(minSdkVersion:29) libvpx(minSdkVersion:29) libwavextractor(minSdkVersion:29) @@ -607,8 +702,8 @@ libyuv_static(minSdkVersion:29) libziparchive(minSdkVersion:apex_inherit) libzstd(minSdkVersion:(no version)) marisa-trie(minSdkVersion:30) -mdns_aidl_interface-lateststable-java(minSdkVersion:29) -mdns_aidl_interface-V1-java(minSdkVersion:29) +mdns_aidl_interface-lateststable-java(minSdkVersion:30) +mdns_aidl_interface-V1-java(minSdkVersion:30) media_ndk_headers(minSdkVersion:29) media_plugin_headers(minSdkVersion:29) MediaProvider(minSdkVersion:30) @@ -619,12 +714,15 @@ metrics-constants-protos(minSdkVersion:current) modules-utils-backgroundthread(minSdkVersion:29) modules-utils-build(minSdkVersion:29) modules-utils-build_system(minSdkVersion:29) +modules-utils-bytesmatcher(minSdkVersion:29) modules-utils-handlerexecutor(minSdkVersion:29) modules-utils-list-slice(minSdkVersion:30) modules-utils-os(minSdkVersion:30) modules-utils-preconditions(minSdkVersion:29) modules-utils-shell-command-handler(minSdkVersion:29) modules-utils-statemachine(minSdkVersion:29) +modules-utils-synchronous-result-receiver(minSdkVersion:29) +modules-utils-uieventlogger-interface(minSdkVersion:29) ndk_crtbegin_so.21(minSdkVersion:(no version)) ndk_crtbegin_so.27(minSdkVersion:(no version)) ndk_crtend_so.21(minSdkVersion:(no version)) @@ -662,6 +760,7 @@ networkstack-aidl-interfaces-V11-java(minSdkVersion:29) networkstack-aidl-interfaces-V12-java(minSdkVersion:29) networkstack-aidl-interfaces-V13-java(minSdkVersion:29) networkstack-aidl-interfaces-V14-java(minSdkVersion:29) +networkstack-aidl-interfaces-V15-java(minSdkVersion:29) networkstack-aidl-latest(minSdkVersion:29) networkstack-client(minSdkVersion:29) NetworkStackApi29Shims(minSdkVersion:29) @@ -753,6 +852,7 @@ prebuilt_androidx.fragment_fragment-nodeps(minSdkVersion:(no version)) prebuilt_androidx.fragment_fragment-nodeps(minSdkVersion:14) prebuilt_androidx.interpolator_interpolator-nodeps(minSdkVersion:(no version)) prebuilt_androidx.interpolator_interpolator-nodeps(minSdkVersion:14) +prebuilt_androidx.leanback_leanback-grid-nodeps(minSdkVersion:17) prebuilt_androidx.leanback_leanback-nodeps(minSdkVersion:(no version)) prebuilt_androidx.leanback_leanback-nodeps(minSdkVersion:17) prebuilt_androidx.leanback_leanback-preference-nodeps(minSdkVersion:(no version)) @@ -849,8 +949,11 @@ prebuilt_androidx.viewpager_viewpager-nodeps(minSdkVersion:14) prebuilt_androidx.window_window-nodeps(minSdkVersion:14) prebuilt_androidx.work_work-runtime-nodeps(minSdkVersion:14) prebuilt_asm-7.0(minSdkVersion:current) +prebuilt_asm-9.2(minSdkVersion:current) prebuilt_asm-commons-7.0(minSdkVersion:current) +prebuilt_asm-commons-9.2(minSdkVersion:current) prebuilt_asm-tree-7.0(minSdkVersion:current) +prebuilt_asm-tree-9.2(minSdkVersion:current) prebuilt_bionic_libc_platform_headers(minSdkVersion:(no version)) prebuilt_car-ui-lib-nodeps(minSdkVersion:28) prebuilt_com.google.android.material_material-nodeps(minSdkVersion:(no version)) @@ -870,20 +973,19 @@ prebuilt_guava-listenablefuture-prebuilt-jar(minSdkVersion:29) prebuilt_guava-listenablefuture-prebuilt-jar(minSdkVersion:current) prebuilt_jni_headers(minSdkVersion:(no version)) prebuilt_kotlin-stdlib(minSdkVersion:current) +prebuilt_kotlin-stdlib-jdk8(minSdkVersion:current) prebuilt_kotlinx-coroutines-android-nodeps(minSdkVersion:(no version)) prebuilt_kotlinx-coroutines-android-nodeps(minSdkVersion:current) prebuilt_kotlinx-coroutines-core-nodeps(minSdkVersion:(no version)) prebuilt_kotlinx-coroutines-core-nodeps(minSdkVersion:current) prebuilt_libasync_safe(minSdkVersion:(no version)) prebuilt_libc_headers(minSdkVersion:(no version)) +prebuilt_libclang_rt.builtins(minSdkVersion:(no version)) prebuilt_libclang_rt.builtins-aarch64-android(minSdkVersion:(no version)) prebuilt_libclang_rt.builtins-arm-android(minSdkVersion:(no version)) prebuilt_libclang_rt.builtins-i686-android(minSdkVersion:(no version)) prebuilt_libclang_rt.builtins-x86_64-android(minSdkVersion:(no version)) -prebuilt_libclang_rt.ubsan_minimal-aarch64-android(minSdkVersion:(no version)) -prebuilt_libclang_rt.ubsan_minimal-arm-android(minSdkVersion:(no version)) -prebuilt_libclang_rt.ubsan_minimal-i686-android(minSdkVersion:(no version)) -prebuilt_libclang_rt.ubsan_minimal-x86_64-android(minSdkVersion:(no version)) +prebuilt_libclang_rt.ubsan_minimal(minSdkVersion:(no version)) prebuilt_libnativehelper_header_only(minSdkVersion:(no version)) prebuilt_libperfetto_client_experimental(minSdkVersion:(no version)) prebuilt_libunwind(minSdkVersion:(no version)) @@ -891,6 +993,7 @@ prebuilt_perfetto_trace_protos(minSdkVersion:(no version)) prebuilt_test_framework-sdkextensions(minSdkVersion:(no version)) resourceobserver_aidl_interface-V1-ndk(minSdkVersion:29) resourceobserver_aidl_interface-V1-ndk_platform(minSdkVersion:29) +sap-api-java-static(minSdkVersion:30) server_configurable_flags(minSdkVersion:29) ServiceWifiResourcesGoogle(minSdkVersion:30) SettingsLibActionBarShadow(minSdkVersion:21) diff --git a/build/build_unbundled_mainline_module.sh b/build/build_unbundled_mainline_module.sh index d85d74ab..84bf71d5 100755 --- a/build/build_unbundled_mainline_module.sh +++ b/build/build_unbundled_mainline_module.sh @@ -68,7 +68,6 @@ readonly -a DEFAULT_MODULES=( CaptivePortalLogin DocumentsUI ExtServices - NetworkPermissionConfig NetworkStack NetworkStackNext PermissionController diff --git a/build/mainline_modules_sdks.py b/build/mainline_modules_sdks.py index 0b4e9d9b..3cef2478 100755 --- a/build/mainline_modules_sdks.py +++ b/build/mainline_modules_sdks.py @@ -18,7 +18,7 @@ If the environment variable TARGET_BUILD_APPS is nonempty then only the SDKs for the APEXes in it are built, otherwise all configured SDKs are built. """ - +import argparse import dataclasses import io import os @@ -28,9 +28,28 @@ import subprocess import sys import tempfile import typing +from collections import defaultdict from typing import Callable, List import zipfile +COPYRIGHT_BOILERPLATE = """ +// +// Copyright (C) 2020 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. +// +""".lstrip() + @dataclasses.dataclass(frozen=True) class ConfigVar: @@ -73,7 +92,7 @@ class SoongConfigBoilerplateInserter(FileTransformation): configModuleTypePrefix: str def apply(self, producer, path): - with open(path, "r+") as file: + with open(path, "r+", encoding="utf8") as file: self._apply_transformation(producer, file) def _apply_transformation(self, producer, file): @@ -134,7 +153,7 @@ class SoongConfigBoilerplateInserter(FileTransformation): namespace = self.configVar.namespace name = self.configVar.name module_content.append(f"""\ - // Do not prefer prebuilt if SOONG_CONFIG_{namespace}_{name} is true. + // Do not prefer prebuilt if the Soong config variable "{name}" in namespace "{namespace}" is true. prefer: true, soong_config_variables: {{ {name}: {{ @@ -197,23 +216,34 @@ class SubprocessRunner: *args, check=True, stdout=self.stdout, stderr=self.stderr, **kwargs) +def sdk_snapshot_zip_file(snapshots_dir, sdk_name, sdk_version): + """Get the path to the sdk snapshot zip file.""" + return os.path.join(snapshots_dir, f"{sdk_name}-{sdk_version}.zip") + + @dataclasses.dataclass() class SnapshotBuilder: """Builds sdk snapshots""" + # The path to this tool. + tool_path: str + # Used to run subprocesses for building snapshots. subprocess_runner: SubprocessRunner # The OUT_DIR environment variable. out_dir: str - def get_mainline_sdks_path(self): - """Get the path to the Soong mainline-sdks directory""" - return os.path.join(self.out_dir, "soong/mainline-sdks") + # The out/soong/mainline-sdks directory. + mainline_sdks_dir: str = "" + + def __post_init__(self): + self.mainline_sdks_dir = os.path.join(self.out_dir, + "soong/mainline-sdks") def get_sdk_path(self, sdk_name, sdk_version): """Get the path to the sdk snapshot zip file produced by soong""" - return os.path.join(self.get_mainline_sdks_path(), + return os.path.join(self.mainline_sdks_dir, f"{sdk_name}-{sdk_version}.zip") def build_snapshots(self, build_release, sdk_versions, modules): @@ -222,7 +252,7 @@ class SnapshotBuilder: # Compute the paths to all the Soong generated sdk snapshot files # required by this script. paths = [ - self.get_sdk_path(sdk, sdk_version) + sdk_snapshot_zip_file(self.mainline_sdks_dir, sdk, sdk_version) for module in modules for sdk in module.sdks ] @@ -246,12 +276,13 @@ class SnapshotBuilder: # This MUST be identical to the TARGET_BUILD_VARIANT used to build # the corresponding APEXes otherwise it could result in different # hidden API flags, see http://b/202398851#comment29 for more info. - targetBuildVariant = os.environ.get("TARGET_BUILD_VARIANT", "user") + target_build_variant = os.environ.get("TARGET_BUILD_VARIANT", + "user") cmd = [ "build/soong/soong_ui.bash", "--make-mode", "--soong-only", - f"TARGET_BUILD_VARIANT={targetBuildVariant}", + f"TARGET_BUILD_VARIANT={target_build_variant}", "TARGET_PRODUCT=mainline_sdk", "MODULE_BUILD_FROM_SOURCE=true", "out/soong/apex/depsinfo/new-allowed-deps.txt.check", @@ -260,6 +291,93 @@ class SnapshotBuilder: env = os.environ.copy() env.update(extraEnv) self.subprocess_runner.run(cmd, env=env) + return self.mainline_sdks_dir + + def build_snapshots_for_build_r(self, build_release, sdk_versions, modules): + # Build the snapshots as standard. + snapshot_dir = self.build_snapshots(build_release, sdk_versions, + modules) + + # Each module will extract needed files from the original snapshot zip + # file and then use that to create a replacement zip file. + r_snapshot_dir = os.path.join(snapshot_dir, "for-R-build") + shutil.rmtree(r_snapshot_dir, ignore_errors=True) + + build_number_file = os.path.join(self.out_dir, "soong/build_number.txt") + + for module in modules: + apex = module.apex + dest_dir = os.path.join(r_snapshot_dir, apex) + os.makedirs(dest_dir, exist_ok=True) + + # Write the bp file in the sdk_library sub-directory rather than the + # root of the zip file as it will be unpacked in a directory that + # already contains an Android.bp file that defines the corresponding + # apex_set. + bp_file = os.path.join(dest_dir, "sdk_library/Android.bp") + os.makedirs(os.path.dirname(bp_file), exist_ok=True) + + # The first sdk in the list is the name to use. + sdk_name = module.sdks[0] + + with open(bp_file, "w", encoding="utf8") as bp: + bp.write("// DO NOT EDIT. Auto-generated by the following:\n") + bp.write(f"// {self.tool_path}\n") + bp.write(COPYRIGHT_BOILERPLATE) + aosp_apex = google_to_aosp_name(apex) + + for library in module.for_r_build.sdk_libraries: + module_name = library.name + shared_library = str(library.shared_library).lower() + sdk_file = sdk_snapshot_zip_file(snapshot_dir, sdk_name, + "current") + extract_matching_files_from_zip( + sdk_file, dest_dir, + sdk_library_files_pattern( + scope_pattern=r"(public|system|module-lib)", + name_pattern=fr"({module_name}(-removed|-stubs)?)")) + + bp.write(f""" +java_sdk_library_import {{ + name: "{module_name}", + owner: "google", + prefer: true, + shared_library: {shared_library}, + apex_available: [ + "{aosp_apex}", + "test_{aosp_apex}", + ], + public: {{ + jars: ["public/{module_name}-stubs.jar"], + current_api: "public/{module_name}.txt", + removed_api: "public/{module_name}-removed.txt", + sdk_version: "module_current", + }}, + system: {{ + jars: ["system/{module_name}-stubs.jar"], + current_api: "system/{module_name}.txt", + removed_api: "system/{module_name}-removed.txt", + sdk_version: "module_current", + }}, + module_lib: {{ + jars: ["module-lib/{module_name}-stubs.jar"], + current_api: "module-lib/{module_name}.txt", + removed_api: "module-lib/{module_name}-removed.txt", + sdk_version: "module_current", + }}, +}} +""") + + # Copy the build_number.txt file into the snapshot. + snapshot_build_number_file = os.path.join( + dest_dir, "snapshot-creation-build-number.txt") + shutil.copy(build_number_file, snapshot_build_number_file) + + # Now zip up the files into a snapshot zip file. + base_file = os.path.join(r_snapshot_dir, sdk_name + "-current") + shutil.make_archive(base_file, "zip", dest_dir) + + return r_snapshot_dir # A list of the sdk versions to build. Usually just current but can include a @@ -310,6 +428,10 @@ class BuildRelease: # The position of this instance within the BUILD_RELEASES list. ordinal: int = dataclasses.field(default=-1, init=False) + # Whether this build release supports the Soong config boilerplate that is + # used to control the prefer setting of modules via a Soong config variable. + supports_soong_config_boilerplate: bool = True + def __post_init__(self): # The following use object.__setattr__ as this object is frozen and # attempting to set the fields directly would cause an exception to be @@ -335,28 +457,62 @@ class BuildRelease: return self.ordinal <= other.ordinal -def create_no_dist_snapshot(build_release: BuildRelease, - producer: "SdkDistProducer", +def create_no_dist_snapshot(_: BuildRelease, __: "SdkDistProducer", modules: List["MainlineModule"]): """A place holder dist snapshot creation function that does nothing.""" print(f"create_no_dist_snapshot for modules {[m.apex for m in modules]}") - return -def create_sdk_snapshots_in_Soong(build_release: BuildRelease, +def create_dist_snapshot_for_r(build_release: BuildRelease, + producer: "SdkDistProducer", + modules: List["MainlineModule"]): + """Generate a snapshot suitable for use in an R build.""" + producer.product_dist_for_build_r(build_release, modules) + + +def create_sdk_snapshots_in_soong(build_release: BuildRelease, producer: "SdkDistProducer", modules: List["MainlineModule"]): - """Builds sdks and populates the dist.""" - producer.produce_dist_for_build_release(build_release, modules) - return + """Builds sdks and populates the dist for unbundled modules.""" + producer.produce_unbundled_dist_for_build_release(build_release, modules) -def reuse_latest_sdk_snapshots(build_release: BuildRelease, - producer: "SdkDistProducer", - modules: List["MainlineModule"]): - """Copies the snapshots from the latest build.""" - producer.populate_dist(build_release, build_release.sdk_versions, modules) - return +def create_latest_sdk_snapshots(build_release: BuildRelease, + producer: "SdkDistProducer", + modules: List["MainlineModule"]): + """Builds and populates the latest release, including bundled modules.""" + producer.produce_unbundled_dist_for_build_release(build_release, modules) + producer.produce_bundled_dist_for_build_release(build_release, modules) + + +def create_legacy_dist_structures(build_release: BuildRelease, + producer: "SdkDistProducer", + modules: List["MainlineModule"]): + """Creates legacy file structures.""" + + # Only put unbundled modules in the legacy dist and stubs structures. + modules = [m for m in modules if not m.is_bundled()] + + snapshots_dir = producer.produce_unbundled_dist_for_build_release( + build_release, modules) + + # Create the out/dist/mainline-sdks/stubs structure. + # TODO(b/199759953): Remove stubs once it is no longer used by gantry. + # Clear and populate the stubs directory. + dist_dir = producer.dist_dir + stubs_dir = os.path.join(dist_dir, "stubs") + shutil.rmtree(stubs_dir, ignore_errors=True) + + for module in modules: + apex = module.apex + dest_dir = os.path.join(dist_dir, "stubs", apex) + for sdk in module.sdks: + # If the sdk's name ends with -sdk then extract sdk library + # related files from its zip file. + if sdk.endswith("-sdk"): + sdk_file = sdk_snapshot_zip_file(snapshots_dir, sdk, "current") + extract_matching_files_from_zip(sdk_file, dest_dir, + sdk_library_files_pattern()) Q = BuildRelease( @@ -366,13 +522,24 @@ Q = BuildRelease( ) R = BuildRelease( name="R", - # At the moment we do not generate a snapshot for R. - creator=create_no_dist_snapshot, -) + # Generate a simple snapshot for R. + creator=create_dist_snapshot_for_r, + # By default a BuildRelease creates an environment to pass to Soong that + # creates a release specific snapshot. However, Soong does not yet (and is + # unlikely to) support building an sdk snapshot for R so create an empty + # environment to pass to Soong instead. + soong_env={}, + # R does not support or need Soong config boilerplate. + supports_soong_config_boilerplate=False) S = BuildRelease( name="S", # Generate a snapshot for S using Soong. - creator=create_sdk_snapshots_in_Soong, + creator=create_sdk_snapshots_in_soong, +) +Tiramisu = BuildRelease( + name="Tiramisu", + # Generate a snapshot for Tiramisu using Soong. + creator=create_sdk_snapshots_in_soong, ) # Insert additional BuildRelease definitions for following releases here, @@ -383,7 +550,7 @@ S = BuildRelease( # before LEGACY_BUILD_RELEASE. LATEST = BuildRelease( name="latest", - creator=create_sdk_snapshots_in_Soong, + creator=create_latest_sdk_snapshots, # There are no build release specific environment variables to pass to # Soong. soong_env={}, @@ -396,18 +563,41 @@ LEGACY_BUILD_RELEASE = BuildRelease( name="legacy", # There is no build release specific sub directory. sub_dir="", + # Create snapshots needed for legacy tools. + creator=create_legacy_dist_structures, # There are no build release specific environment variables to pass to # Soong. soong_env={}, - # Do not create new snapshots, simply use the snapshots generated for - # latest. - creator=reuse_latest_sdk_snapshots, ) @dataclasses.dataclass(frozen=True) +class SdkLibrary: + """Information about a java_sdk_library.""" + + # The name of java_sdk_library module. + name: str + + # True if the sdk_library module is a shared library. + shared_library: bool = False + + +@dataclasses.dataclass(frozen=True) +class ForRBuild: + """Data structure needed for generating a snapshot for an R build.""" + + # The java_sdk_library modules to export to the r snapshot. + sdk_libraries: typing.List[SdkLibrary] = dataclasses.field( + default_factory=list) + + +@dataclasses.dataclass(frozen=True) class MainlineModule: - """Represents a mainline module""" + """Represents an unbundled mainline module. + + This is a module that is distributed as a prebuilt and intended to be + updated with Mainline trains. + """ # The name of the apex. apex: str @@ -440,24 +630,59 @@ class MainlineModule: # The prefix to use for the soong config module types. configModuleTypePrefix: str = "module_" - def transformations(self): + for_r_build: typing.Optional[ForRBuild] = None + + def is_bundled(self): + """Returns true for bundled modules. See BundledMainlineModule.""" + return False + + def transformations(self, build_release): """Returns the transformations to apply to this module's snapshot(s).""" - return [ - SoongConfigBoilerplateInserter( + transformations = [] + if build_release.supports_soong_config_boilerplate: + inserter = SoongConfigBoilerplateInserter( "Android.bp", configVar=self.configVar, configModuleTypePrefix=self.configModuleTypePrefix, - configBpDefFile=self.configBpDefFile), - ] + configBpDefFile=self.configBpDefFile) + transformations.append(inserter) + return transformations def is_required_for(self, target_build_release): """True if this module is required for the target build release.""" return self.first_release <= target_build_release +@dataclasses.dataclass(frozen=True) +class BundledMainlineModule(MainlineModule): + """Represents a bundled Mainline module or a platform SDK for module use. + + A bundled module is always preloaded into the platform images. + """ + + def is_bundled(self): + return True + + def transformations(self, build_release): + # Bundled modules are only used on thin branches where the corresponding + # sources are absent, so skip transformations and keep the default + # `prefer: false`. + return [] + + # List of mainline modules. MAINLINE_MODULES = [ MainlineModule( + apex="com.android.adservices", + sdks=["adservices-module-sdk"], + first_release=Tiramisu, + ), + MainlineModule( + apex="com.android.appsearch", + sdks=["appsearch-sdk"], + first_release=Tiramisu, + ), + MainlineModule( apex="com.android.art", sdks=[ "art-module-sdk", @@ -481,26 +706,53 @@ MAINLINE_MODULES = [ "conscrypt-module-host-exports", ], first_release=Q, + # No conscrypt java_sdk_library modules are exported to the R snapshot. + # Conscrypt was updatable in R but the generate_ml_bundle.sh does not + # appear to generate a snapshot for it. + for_r_build=None, ), MainlineModule( apex="com.android.ipsec", sdks=["ipsec-module-sdk"], - first_release=S, + first_release=R, + for_r_build=ForRBuild(sdk_libraries=[ + SdkLibrary( + name="android.net.ipsec.ike", + shared_library=True, + ), + ]), ), MainlineModule( apex="com.android.media", sdks=["media-module-sdk"], first_release=R, + for_r_build=ForRBuild(sdk_libraries=[ + SdkLibrary(name="framework-media"), + ]), ), MainlineModule( apex="com.android.mediaprovider", sdks=["mediaprovider-module-sdk"], first_release=R, + for_r_build=ForRBuild(sdk_libraries=[ + SdkLibrary(name="framework-mediaprovider"), + ]), + ), + MainlineModule( + apex="com.android.ondevicepersonalization", + sdks=["ondevicepersonalization-module-sdk"], + first_release=Tiramisu, ), MainlineModule( apex="com.android.permission", sdks=["permission-module-sdk"], first_release=R, + for_r_build=ForRBuild(sdk_libraries=[ + SdkLibrary(name="framework-permission"), + # framework-permission-s is not needed on R as it contains classes + # that are provided in R by non-updatable parts of the + # bootclasspath. + ]), ), MainlineModule( apex="com.android.scheduling", @@ -510,16 +762,25 @@ MAINLINE_MODULES = [ apex="com.android.sdkext", sdks=["sdkextensions-sdk"], first_release=R, + for_r_build=ForRBuild(sdk_libraries=[ + SdkLibrary(name="framework-sdkextensions"), + ]), ), MainlineModule( apex="com.android.os.statsd", sdks=["statsd-module-sdk"], first_release=R, + for_r_build=ForRBuild(sdk_libraries=[ + SdkLibrary(name="framework-statsd"), + ]), ), MainlineModule( apex="com.android.tethering", sdks=["tethering-module-sdk"], first_release=R, + for_r_build=ForRBuild(sdk_libraries=[ + SdkLibrary(name="framework-tethering"), + ]), ), MainlineModule( apex="com.android.uwb", @@ -529,6 +790,45 @@ MAINLINE_MODULES = [ apex="com.android.wifi", sdks=["wifi-module-sdk"], first_release=R, + for_r_build=ForRBuild(sdk_libraries=[ + SdkLibrary(name="framework-wifi"), + ]), + ), +] + +# List of Mainline modules that currently are never built unbundled. They should +# not specify first_release, and they don't have com.google.android +# counterparts. +BUNDLED_MAINLINE_MODULES = [ + BundledMainlineModule( + apex="com.android.i18n", + sdks=[ + "i18n-module-sdk", + "i18n-module-test-exports", + "i18n-module-host-exports", + ], + ), + BundledMainlineModule( + apex="com.android.runtime", + sdks=[ + "runtime-module-host-exports", + "runtime-module-sdk", + ], + ), + BundledMainlineModule( + apex="com.android.tzdata", + sdks=["tzdata-module-test-exports"], + ), +] + +# List of platform SDKs for Mainline module use. +PLATFORM_SDKS_FOR_MAINLINE = [ + BundledMainlineModule( + apex="platform-mainline", + sdks=[ + "platform-mainline-sdk", + "platform-mainline-test-exports", + ], ), ] @@ -556,23 +856,39 @@ class SdkDistProducer: # transformed to document where the changes came from. script: str = sys.argv[0] - # The path to the mainline-sdks dist directory. + # The path to the mainline-sdks dist directory for unbundled modules. # # Initialized in __post_init__(). mainline_sdks_dir: str = dataclasses.field(init=False) + # The path to the mainline-sdks dist directory for bundled modules and + # platform SDKs. + # + # Initialized in __post_init__(). + bundled_mainline_sdks_dir: str = dataclasses.field(init=False) + def __post_init__(self): self.mainline_sdks_dir = os.path.join(self.dist_dir, "mainline-sdks") + self.bundled_mainline_sdks_dir = os.path.join(self.dist_dir, + "bundled-mainline-sdks") def prepare(self): - # Clear the mainline-sdks dist directory. + # Clear the sdk dist directories. shutil.rmtree(self.mainline_sdks_dir, ignore_errors=True) + shutil.rmtree(self.bundled_mainline_sdks_dir, ignore_errors=True) def produce_dist(self, modules, build_releases): # Prepare the dist directory for the sdks. self.prepare() + # Group build releases so that those with the same Soong environment are + # run consecutively to avoid having to regenerate ninja files. + grouped_by_env = defaultdict(list) for build_release in build_releases: + grouped_by_env[str(build_release.soong_env)].append(build_release) + ordered = [br for _, group in grouped_by_env.items() for br in group] + + for build_release in ordered: # Only build modules that are required for this build release. filtered_modules = [ m for m in modules if m.is_required_for(build_release) @@ -582,60 +898,69 @@ class SdkDistProducer: f" build release") build_release.creator(build_release, self, filtered_modules) - self.populate_stubs(modules) - - def produce_dist_for_build_release(self, build_release, modules): + def product_dist_for_build_r(self, build_release, modules): + # Although we only need a subset of the files that a java_sdk_library + # adds to an sdk snapshot generating the whole snapshot is the simplest + # way to ensure that all the necessary files are produced. sdk_versions = build_release.sdk_versions - self.snapshot_builder.build_snapshots(build_release, sdk_versions, - modules) - self.populate_dist(build_release, sdk_versions, modules) - - def unzip_current_stubs(self, sdk_name, apex_name): - """Unzips stubs for "current" into {producer.dist_dir}/stubs/{apex}.""" - sdk_path = self.snapshot_builder.get_sdk_path(sdk_name, "current") - dest_dir = os.path.join(self.dist_dir, "stubs", apex_name) - print( - f"Extracting java_sdk_library files from {sdk_path} to {dest_dir}") - os.makedirs(dest_dir, exist_ok=True) - extract_matching_files_from_zip( - sdk_path, dest_dir, r"sdk_library/[^/]+/[^/]+\.(txt|jar|srcjar)") - - def populate_stubs(self, modules): - # TODO(b/199759953): Remove stubs once it is no longer used by gantry. - # Clear and populate the stubs directory. - stubs_dir = os.path.join(self.dist_dir, "stubs") - shutil.rmtree(stubs_dir, ignore_errors=True) - for module in modules: - apex = module.apex - for sdk in module.sdks: - # If the sdk's name ends with -sdk then extract sdk library - # related files from its zip file. - if sdk.endswith("-sdk"): - self.unzip_current_stubs(sdk, apex) + # Filter out any modules that do not provide sdk for R. + modules = [m for m in modules if m.for_r_build] - def populate_dist(self, build_release, sdk_versions, modules): + snapshot_dir = self.snapshot_builder.build_snapshots_for_build_r( + build_release, sdk_versions, modules) + self.populate_unbundled_dist(build_release, sdk_versions, modules, + snapshot_dir) + + def produce_unbundled_dist_for_build_release(self, build_release, modules): + modules = [m for m in modules if not m.is_bundled()] + sdk_versions = build_release.sdk_versions + snapshots_dir = self.snapshot_builder.build_snapshots( + build_release, sdk_versions, modules) + self.populate_unbundled_dist(build_release, sdk_versions, modules, + snapshots_dir) + return snapshots_dir + + def produce_bundled_dist_for_build_release(self, build_release, modules): + modules = [m for m in modules if m.is_bundled()] + if modules: + sdk_versions = build_release.sdk_versions + snapshots_dir = self.snapshot_builder.build_snapshots( + build_release, sdk_versions, modules) + self.populate_bundled_dist(build_release, modules, snapshots_dir) + + def populate_unbundled_dist(self, build_release, sdk_versions, modules, + snapshots_dir): build_release_dist_dir = os.path.join(self.mainline_sdks_dir, build_release.sub_dir) - for module in modules: - apex = module.apex for sdk_version in sdk_versions: for sdk in module.sdks: - subdir = re.sub("^[^-]+-(module-)?", "", sdk) - if subdir not in ("sdk", "host-exports", "test-exports"): - raise Exception( - f"{sdk} is not a valid name, expected name in the" - f" format of" - f" ^[^-]+-(module-)?(sdk|host-exports|test-exports)" - ) - sdk_dist_dir = os.path.join(build_release_dist_dir, - sdk_version, apex, subdir) - sdk_path = self.snapshot_builder.get_sdk_path( - sdk, sdk_version) - self.dist_sdk_snapshot_zip(sdk_path, sdk_dist_dir, - module.transformations()) + sdk_version) + self.populate_dist_snapshot(build_release, module, sdk, + sdk_dist_dir, sdk_version, + snapshots_dir) + + def populate_bundled_dist(self, build_release, modules, snapshots_dir): + sdk_dist_dir = self.bundled_mainline_sdks_dir + for module in modules: + for sdk in module.sdks: + self.populate_dist_snapshot(build_release, module, sdk, + sdk_dist_dir, "current", + snapshots_dir) + + def populate_dist_snapshot(self, build_release, module, sdk, sdk_dist_dir, + sdk_version, snapshots_dir): + subdir = re.sub("^.+-(sdk|(host|test)-exports)$", r"\1", sdk) + if subdir not in ("sdk", "host-exports", "test-exports"): + raise Exception(f"{sdk} is not a valid name, expected it to end" + f" with -(sdk|host-exports|test-exports)") + + sdk_dist_subdir = os.path.join(sdk_dist_dir, module.apex, subdir) + sdk_path = sdk_snapshot_zip_file(snapshots_dir, sdk, sdk_version) + transformations = module.transformations(build_release) + self.dist_sdk_snapshot_zip(sdk_path, sdk_dist_subdir, transformations) def dist_sdk_snapshot_zip(self, src_sdk_zip, sdk_dist_dir, transformations): """Copy the sdk snapshot zip file to a dist directory. @@ -681,15 +1006,22 @@ def print_command(env, cmd): print(" ".join([f"{name}={value}" for name, value in env.items()] + cmd)) +def sdk_library_files_pattern(*, scope_pattern=r"[^/]+", name_pattern=r"[^/]+"): + """Return a pattern to match sdk_library related files in an sdk snapshot""" + return rf"sdk_library/{scope_pattern}/{name_pattern}\.(txt|jar|srcjar)" + + def extract_matching_files_from_zip(zip_path, dest_dir, pattern): """Extracts files from a zip file into a destination directory. The extracted files are those that match the specified regular expression pattern. """ + os.makedirs(dest_dir, exist_ok=True) with zipfile.ZipFile(zip_path) as zip_file: for filename in zip_file.namelist(): if re.match(pattern, filename): + print(f" extracting {filename}") zip_file.extract(filename, dest_dir) @@ -724,14 +1056,19 @@ def apply_transformations(producer, tmp_dir, transformations): os.utime(path, (modified, modified)) -def create_producer(): +def create_producer(tool_path): # Variables initialized from environment variables that are set by the # calling mainline_modules_sdks.sh. out_dir = os.environ["OUT_DIR"] dist_dir = os.environ["DIST_DIR"] + top_dir = os.environ["ANDROID_BUILD_TOP"] + tool_path = os.path.relpath(tool_path, top_dir) + tool_path = tool_path.replace(".py", ".sh") + subprocess_runner = SubprocessRunner() snapshot_builder = SnapshotBuilder( + tool_path=tool_path, subprocess_runner=subprocess_runner, out_dir=out_dir, ) @@ -742,25 +1079,79 @@ def create_producer(): ) -def filter_modules(modules): - target_build_apps = os.environ.get("TARGET_BUILD_APPS") +def aosp_to_google(module): + """Transform an AOSP module into a Google module""" + new_apex = aosp_to_google_name(module.apex) + # Create a copy of the AOSP module with the internal specific APEX name. + return dataclasses.replace(module, apex=new_apex) + + +def aosp_to_google_name(name): + """Transform an AOSP module name into a Google module name""" + return name.replace("com.android.", "com.google.android.") + + +def google_to_aosp_name(name): + """Transform a Google module name into an AOSP module name""" + return name.replace("com.google.android.", "com.android.") + + +def filter_modules(modules, target_build_apps): if target_build_apps: target_build_apps = target_build_apps.split() return [m for m in modules if m.apex in target_build_apps] - else: - return modules + return modules -def main(): +def main(args): """Program entry point.""" if not os.path.exists("build/make/core/Makefile"): sys.exit("This script must be run from the top of the tree.") - producer = create_producer() - modules = filter_modules(MAINLINE_MODULES) + args_parser = argparse.ArgumentParser( + description="Build snapshot zips for consumption by Gantry.") + args_parser.add_argument( + "--tool-path", + help="The path to this tool.", + default="unspecified", + ) + args_parser.add_argument( + "--build-release", + action="append", + choices=[br.name for br in ALL_BUILD_RELEASES], + help="A target build for which snapshots are required. " + "If it is \"latest\" then Mainline module SDKs from platform and " + "bundled modules are included.", + ) + args_parser.add_argument( + "--build-platform-sdks-for-mainline", + action="store_true", + help="Also build the platform SDKs for Mainline modules. " + "Defaults to true when TARGET_BUILD_APPS is not set. " + "Applicable only if the \"latest\" build release is built.", + ) + args = args_parser.parse_args(args) + + build_releases = ALL_BUILD_RELEASES + if args.build_release: + selected_build_releases = {b.lower() for b in args.build_release} + build_releases = [ + b for b in build_releases + if b.name.lower() in selected_build_releases + ] + + target_build_apps = os.environ.get("TARGET_BUILD_APPS") + modules = filter_modules(MAINLINE_MODULES + BUNDLED_MAINLINE_MODULES, + target_build_apps) + + # Also build the platform Mainline SDKs either if no specific modules are + # requested or if --build-platform-sdks-for-mainline is given. + if not target_build_apps or args.build_platform_sdks_for_mainline: + modules += PLATFORM_SDKS_FOR_MAINLINE - producer.produce_dist(modules, ALL_BUILD_RELEASES) + producer = create_producer(args.tool_path) + producer.produce_dist(modules, build_releases) if __name__ == "__main__": - main() + main(sys.argv[1:]) diff --git a/build/mainline_modules_sdks.sh b/build/mainline_modules_sdks.sh index fb5cfd36..35a677ed 100755 --- a/build/mainline_modules_sdks.sh +++ b/build/mainline_modules_sdks.sh @@ -56,7 +56,15 @@ function main() { # provided by the build to ensure consistency across build environments. export DIST_DIR OUT_DIR - prebuilts/build-tools/linux-x86/bin/py3-cmd -u "${py3script}" + # Make sure that the ANDROID_BUILD_TOP (which is the same as the current + # directory as checked above) is exported to Python. + export ANDROID_BUILD_TOP="${PWD}" + + # The path to this tool is the .sh script that lives alongside the .py script. + TOOL_PATH="${py3script%.py}.sh" + prebuilts/build-tools/linux-x86/bin/py3-cmd -u "${py3script}" \ + --tool-path "${TOOL_PATH}" \ + "$@" } init "$@" diff --git a/build/mainline_modules_sdks_test.py b/build/mainline_modules_sdks_test.py index d4d6faaa..6d06303c 100644 --- a/build/mainline_modules_sdks_test.py +++ b/build/mainline_modules_sdks_test.py @@ -15,17 +15,25 @@ # limitations under the License. """Unit tests for mainline_modules_sdks.py.""" import dataclasses +import pathlib +import re +import typing from pathlib import Path import os +import shutil import tempfile import unittest import zipfile +from unittest import mock import mainline_modules_sdks as mm -MAINLINE_MODULES_BY_APEX = dict((m.apex, m) for m in mm.MAINLINE_MODULES) +MAINLINE_MODULES_BY_APEX = dict( + (m.apex, m) for m in (mm.MAINLINE_MODULES + mm.BUNDLED_MAINLINE_MODULES + + mm.PLATFORM_SDKS_FOR_MAINLINE)) +@dataclasses.dataclass() class FakeSnapshotBuilder(mm.SnapshotBuilder): """A fake snapshot builder that does not run the build. @@ -33,101 +41,316 @@ class FakeSnapshotBuilder(mm.SnapshotBuilder): modules. """ - def create_snapshot_file(self, name, version): - zip_file = Path(self.get_sdk_path(name, version)) + snapshots: typing.List[typing.Any] = dataclasses.field(default_factory=list) + + @staticmethod + def create_sdk_library_files(z, name): + z.writestr(f"sdk_library/public/{name}-removed.txt", "") + z.writestr(f"sdk_library/public/{name}.srcjar", "") + z.writestr(f"sdk_library/public/{name}-stubs.jar", "") + z.writestr(f"sdk_library/public/{name}.txt", "") + + def create_snapshot_file(self, out_dir, name, version, for_r_build): + zip_file = Path(mm.sdk_snapshot_zip_file(out_dir, name, version)) with zipfile.ZipFile(zip_file, "w") as z: z.writestr("Android.bp", "") if name.endswith("-sdk"): - z.writestr("sdk_library/public/removed.txt", "") - z.writestr("sdk_library/public/source.srcjar", "") - z.writestr("sdk_library/public/lib.jar", "") - z.writestr("sdk_library/public/api.txt", "") + if for_r_build: + for library in for_r_build.sdk_libraries: + self.create_sdk_library_files(z, library.name) + else: + self.create_sdk_library_files(z, re.sub(r"-.*$", "", name)) def build_snapshots(self, build_release, sdk_versions, modules): + self.snapshots.append((build_release.name, build_release.soong_env, + sdk_versions, [m.apex for m in modules])) # Create input file structure. - sdks_out_dir = Path(self.get_mainline_sdks_path()) + sdks_out_dir = Path(self.mainline_sdks_dir).joinpath("test") sdks_out_dir.mkdir(parents=True, exist_ok=True) # Create a fake sdk zip file for each module. for module in modules: for sdk in module.sdks: for sdk_version in sdk_versions: - self.create_snapshot_file(sdk, sdk_version) + self.create_snapshot_file(sdks_out_dir, sdk, sdk_version, + module.for_r_build) + return sdks_out_dir class TestProduceDist(unittest.TestCase): - def test(self): - """Verify the dist/mainline-sdks directory is populated correctly""" - with tempfile.TemporaryDirectory() as tmp_dir: - tmp_out_dir = os.path.join(tmp_dir, "out") - os.mkdir(tmp_out_dir) - tmp_dist_dir = os.path.join(tmp_dir, "dist") - os.mkdir(tmp_dist_dir) - - modules = [ - MAINLINE_MODULES_BY_APEX["com.android.art"], - MAINLINE_MODULES_BY_APEX["com.android.ipsec"], - ] - - subprocess_runner = mm.SubprocessRunner() - - snapshot_builder = FakeSnapshotBuilder( - subprocess_runner=subprocess_runner, - out_dir=tmp_out_dir, - ) - - build_releases = [ - mm.Q, - mm.R, - mm.S, - mm.LATEST, - mm.LEGACY_BUILD_RELEASE, - ] - - producer = mm.SdkDistProducer( - subprocess_runner=subprocess_runner, - snapshot_builder=snapshot_builder, - dist_dir=tmp_dist_dir, - ) - - producer.produce_dist(modules, build_releases) - - files = [] - for abs_dir, _, filenames in os.walk(tmp_dist_dir): - rel_dir = os.path.relpath(abs_dir, tmp_dist_dir) - for f in filenames: - files.append(os.path.join(rel_dir, f)) - # pylint: disable=line-too-long - self.assertEqual( + def setUp(self): + self.tmp_dir = tempfile.mkdtemp() + self.tmp_out_dir = os.path.join(self.tmp_dir, "out") + os.mkdir(self.tmp_out_dir) + self.tmp_dist_dir = os.path.join(self.tmp_dir, "dist") + os.mkdir(self.tmp_dist_dir) + + def tearDown(self): + shutil.rmtree(self.tmp_dir, ignore_errors=True) + + def produce_dist(self, modules, build_releases): + subprocess_runner = mm.SubprocessRunner() + snapshot_builder = FakeSnapshotBuilder( + tool_path="path/to/mainline_modules_sdks.sh", + subprocess_runner=subprocess_runner, + out_dir=self.tmp_out_dir, + ) + producer = mm.SdkDistProducer( + subprocess_runner=subprocess_runner, + snapshot_builder=snapshot_builder, + dist_dir=self.tmp_dist_dir, + ) + producer.produce_dist(modules, build_releases) + + def list_files_in_dir(self, tmp_dist_dir): + files = [] + for abs_dir, _, filenames in os.walk(tmp_dist_dir): + rel_dir = os.path.relpath(abs_dir, tmp_dist_dir) + if rel_dir == ".": + rel_dir = "" + for f in filenames: + files.append(os.path.join(rel_dir, f)) + return files + + def test_unbundled_modules(self): + # Create the out/soong/build_number.txt file that is copied into the + # snapshots. + self.create_build_number_file() + + modules = [ + MAINLINE_MODULES_BY_APEX["com.android.art"], + MAINLINE_MODULES_BY_APEX["com.android.ipsec"], + # Create a google specific module. + mm.aosp_to_google(MAINLINE_MODULES_BY_APEX["com.android.wifi"]), + ] + build_releases = [ + mm.Q, + mm.R, + mm.S, + mm.LATEST, + mm.LEGACY_BUILD_RELEASE, + ] + self.produce_dist(modules, build_releases) + + # pylint: disable=line-too-long + self.assertEqual( + [ + # Legacy copy of the snapshots, for use by tools that don't support build specific snapshots. + "mainline-sdks/current/com.android.art/host-exports/art-module-host-exports-current.zip", + "mainline-sdks/current/com.android.art/sdk/art-module-sdk-current.zip", + "mainline-sdks/current/com.android.art/test-exports/art-module-test-exports-current.zip", + "mainline-sdks/current/com.android.ipsec/sdk/ipsec-module-sdk-current.zip", + "mainline-sdks/current/com.google.android.wifi/sdk/wifi-module-sdk-current.zip", + # Build specific snapshots. + "mainline-sdks/for-R-build/current/com.android.ipsec/sdk/ipsec-module-sdk-current.zip", + "mainline-sdks/for-R-build/current/com.google.android.wifi/sdk/wifi-module-sdk-current.zip", + "mainline-sdks/for-S-build/current/com.android.art/host-exports/art-module-host-exports-current.zip", + "mainline-sdks/for-S-build/current/com.android.art/sdk/art-module-sdk-current.zip", + "mainline-sdks/for-S-build/current/com.android.art/test-exports/art-module-test-exports-current.zip", + "mainline-sdks/for-S-build/current/com.android.ipsec/sdk/ipsec-module-sdk-current.zip", + "mainline-sdks/for-S-build/current/com.google.android.wifi/sdk/wifi-module-sdk-current.zip", + "mainline-sdks/for-latest-build/current/com.android.art/host-exports/art-module-host-exports-current.zip", + "mainline-sdks/for-latest-build/current/com.android.art/sdk/art-module-sdk-current.zip", + "mainline-sdks/for-latest-build/current/com.android.art/test-exports/art-module-test-exports-current.zip", + "mainline-sdks/for-latest-build/current/com.android.ipsec/sdk/ipsec-module-sdk-current.zip", + "mainline-sdks/for-latest-build/current/com.google.android.wifi/sdk/wifi-module-sdk-current.zip", + # Legacy stubs directory containing unpacked java_sdk_library artifacts. + "stubs/com.android.art/sdk_library/public/art-removed.txt", + "stubs/com.android.art/sdk_library/public/art-stubs.jar", + "stubs/com.android.art/sdk_library/public/art.srcjar", + "stubs/com.android.art/sdk_library/public/art.txt", + "stubs/com.android.ipsec/sdk_library/public/android.net.ipsec.ike-removed.txt", + "stubs/com.android.ipsec/sdk_library/public/android.net.ipsec.ike-stubs.jar", + "stubs/com.android.ipsec/sdk_library/public/android.net.ipsec.ike.srcjar", + "stubs/com.android.ipsec/sdk_library/public/android.net.ipsec.ike.txt", + "stubs/com.google.android.wifi/sdk_library/public/framework-wifi-removed.txt", + "stubs/com.google.android.wifi/sdk_library/public/framework-wifi-stubs.jar", + "stubs/com.google.android.wifi/sdk_library/public/framework-wifi.srcjar", + "stubs/com.google.android.wifi/sdk_library/public/framework-wifi.txt", + ], + sorted(self.list_files_in_dir(self.tmp_dist_dir))) + + r_snaphot_dir = os.path.join(self.tmp_out_dir, + "soong/mainline-sdks/test/for-R-build") + aosp_ipsec_r_bp_file = "com.android.ipsec/sdk_library/Android.bp" + google_wifi_android_bp = "com.google.android.wifi/sdk_library/Android.bp" + self.assertEqual([ + aosp_ipsec_r_bp_file, + "com.android.ipsec/sdk_library/public/android.net.ipsec.ike-removed.txt", + "com.android.ipsec/sdk_library/public/android.net.ipsec.ike-stubs.jar", + "com.android.ipsec/sdk_library/public/android.net.ipsec.ike.srcjar", + "com.android.ipsec/sdk_library/public/android.net.ipsec.ike.txt", + "com.android.ipsec/snapshot-creation-build-number.txt", + google_wifi_android_bp, + "com.google.android.wifi/sdk_library/public/framework-wifi-removed.txt", + "com.google.android.wifi/sdk_library/public/framework-wifi-stubs.jar", + "com.google.android.wifi/sdk_library/public/framework-wifi.srcjar", + "com.google.android.wifi/sdk_library/public/framework-wifi.txt", + "com.google.android.wifi/snapshot-creation-build-number.txt", + "ipsec-module-sdk-current.zip", + "wifi-module-sdk-current.zip", + ], sorted(self.list_files_in_dir(r_snaphot_dir))) + + def read_r_snapshot_contents(path): + abs_path = os.path.join(r_snaphot_dir, path) + with open(abs_path, "r", encoding="utf8") as file: + return file.read() + + # Check the contents of the AOSP ipsec module + ipsec_contents = read_r_snapshot_contents(aosp_ipsec_r_bp_file) + expected = read_test_data("ipsec_for_r_Android.bp") + self.assertEqual(expected, ipsec_contents) + + # Check the contents of the Google ipsec module + wifi_contents = read_r_snapshot_contents(google_wifi_android_bp) + expected = read_test_data("google_wifi_for_r_Android.bp") + self.assertEqual(expected, wifi_contents) + + def test_old_release(self): + modules = [ + MAINLINE_MODULES_BY_APEX["com.android.art"], # An unnbundled module + MAINLINE_MODULES_BY_APEX["com.android.runtime"], # A bundled module + MAINLINE_MODULES_BY_APEX["platform-mainline"], # Platform SDK + ] + build_releases = [mm.S] + self.produce_dist(modules, build_releases) + + # pylint: disable=line-too-long + self.assertEqual([ + "mainline-sdks/for-S-build/current/com.android.art/host-exports/art-module-host-exports-current.zip", + "mainline-sdks/for-S-build/current/com.android.art/sdk/art-module-sdk-current.zip", + "mainline-sdks/for-S-build/current/com.android.art/test-exports/art-module-test-exports-current.zip", + ], sorted(self.list_files_in_dir(self.tmp_dist_dir))) + + def test_latest_release(self): + modules = [ + MAINLINE_MODULES_BY_APEX["com.android.art"], # An unnbundled module + MAINLINE_MODULES_BY_APEX["com.android.runtime"], # A bundled module + MAINLINE_MODULES_BY_APEX["platform-mainline"], # Platform SDK + ] + build_releases = [mm.LATEST] + self.produce_dist(modules, build_releases) + + # pylint: disable=line-too-long + self.assertEqual( + [ + # Bundled modules and platform SDKs. + "bundled-mainline-sdks/com.android.runtime/host-exports/runtime-module-host-exports-current.zip", + "bundled-mainline-sdks/com.android.runtime/sdk/runtime-module-sdk-current.zip", + "bundled-mainline-sdks/platform-mainline/sdk/platform-mainline-sdk-current.zip", + "bundled-mainline-sdks/platform-mainline/test-exports/platform-mainline-test-exports-current.zip", + # Unbundled (normal) modules. + "mainline-sdks/for-latest-build/current/com.android.art/host-exports/art-module-host-exports-current.zip", + "mainline-sdks/for-latest-build/current/com.android.art/sdk/art-module-sdk-current.zip", + "mainline-sdks/for-latest-build/current/com.android.art/test-exports/art-module-test-exports-current.zip", + ], + sorted(self.list_files_in_dir(self.tmp_dist_dir))) + + def test_legacy_release(self): + modules = [ + MAINLINE_MODULES_BY_APEX["com.android.art"], # An unnbundled module + MAINLINE_MODULES_BY_APEX["com.android.runtime"], # A bundled module + MAINLINE_MODULES_BY_APEX["platform-mainline"], # Platform SDK + ] + build_releases = [mm.LEGACY_BUILD_RELEASE] + self.produce_dist(modules, build_releases) + + # pylint: disable=line-too-long + self.assertEqual( + [ + # Legacy copy of the snapshots. + "mainline-sdks/current/com.android.art/host-exports/art-module-host-exports-current.zip", + "mainline-sdks/current/com.android.art/sdk/art-module-sdk-current.zip", + "mainline-sdks/current/com.android.art/test-exports/art-module-test-exports-current.zip", + # Legacy stubs directory containing unpacked java_sdk_library artifacts. + "stubs/com.android.art/sdk_library/public/art-removed.txt", + "stubs/com.android.art/sdk_library/public/art-stubs.jar", + "stubs/com.android.art/sdk_library/public/art.srcjar", + "stubs/com.android.art/sdk_library/public/art.txt", + ], + sorted(self.list_files_in_dir(self.tmp_dist_dir))) + + def create_build_number_file(self): + soong_dir = os.path.join(self.tmp_out_dir, "soong") + os.makedirs(soong_dir, exist_ok=True) + build_number_file = os.path.join(soong_dir, "build_number.txt") + with open(build_number_file, "w", encoding="utf8") as f: + f.write("build-number") + + def test_snapshot_build_order(self): + # Create the out/soong/build_number.txt file that is copied into the + # snapshots. + self.create_build_number_file() + + subprocess_runner = unittest.mock.Mock(mm.SubprocessRunner) + snapshot_builder = FakeSnapshotBuilder( + tool_path="path/to/mainline_modules_sdks.sh", + subprocess_runner=subprocess_runner, + out_dir=self.tmp_out_dir, + ) + producer = mm.SdkDistProducer( + subprocess_runner=subprocess_runner, + snapshot_builder=snapshot_builder, + dist_dir=self.tmp_dist_dir, + ) + + modules = [ + MAINLINE_MODULES_BY_APEX["com.android.art"], + MAINLINE_MODULES_BY_APEX["com.android.ipsec"], + # Create a google specific module. + mm.aosp_to_google(MAINLINE_MODULES_BY_APEX["com.android.wifi"]), + ] + build_releases = [ + mm.Q, + mm.R, + mm.S, + mm.LATEST, + mm.LEGACY_BUILD_RELEASE, + ] + + producer.produce_dist(modules, build_releases) + + # Check the order in which the snapshots are built. + self.assertEqual([ + ( + "R", + {}, + ["current"], + ["com.android.ipsec", "com.google.android.wifi"], + ), + ( + "latest", + {}, + ["current"], + [ + "com.android.art", "com.android.ipsec", + "com.google.android.wifi" + ], + ), + ( + "legacy", + {}, + ["current"], + [ + "com.android.art", "com.android.ipsec", + "com.google.android.wifi" + ], + ), + ( + "S", + { + "SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S" + }, + ["current"], [ - # Legacy copy of the snapshots, for use by tools that don't support build specific snapshots. - "mainline-sdks/current/com.android.art/host-exports/art-module-host-exports-current.zip", - "mainline-sdks/current/com.android.art/sdk/art-module-sdk-current.zip", - "mainline-sdks/current/com.android.art/test-exports/art-module-test-exports-current.zip", - "mainline-sdks/current/com.android.ipsec/sdk/ipsec-module-sdk-current.zip", - # Build specific snapshots. - "mainline-sdks/for-S-build/current/com.android.art/host-exports/art-module-host-exports-current.zip", - "mainline-sdks/for-S-build/current/com.android.art/sdk/art-module-sdk-current.zip", - "mainline-sdks/for-S-build/current/com.android.art/test-exports/art-module-test-exports-current.zip", - "mainline-sdks/for-S-build/current/com.android.ipsec/sdk/ipsec-module-sdk-current.zip", - "mainline-sdks/for-latest-build/current/com.android.art/host-exports/art-module-host-exports-current.zip", - "mainline-sdks/for-latest-build/current/com.android.art/sdk/art-module-sdk-current.zip", - "mainline-sdks/for-latest-build/current/com.android.art/test-exports/art-module-test-exports-current.zip", - "mainline-sdks/for-latest-build/current/com.android.ipsec/sdk/ipsec-module-sdk-current.zip", - # Legacy stubs directory containing unpacked java_sdk_library artifacts. - "stubs/com.android.art/sdk_library/public/api.txt", - "stubs/com.android.art/sdk_library/public/lib.jar", - "stubs/com.android.art/sdk_library/public/removed.txt", - "stubs/com.android.art/sdk_library/public/source.srcjar", - "stubs/com.android.ipsec/sdk_library/public/api.txt", - "stubs/com.android.ipsec/sdk_library/public/lib.jar", - "stubs/com.android.ipsec/sdk_library/public/removed.txt", - "stubs/com.android.ipsec/sdk_library/public/source.srcjar", + "com.android.art", "com.android.ipsec", + "com.google.android.wifi" ], - sorted(files)) + ), + ], snapshot_builder.snapshots) -def pathToTestData(relative_path): +def path_to_test_data(relative_path): """Construct a path to a test data file. The relative_path is relative to the location of this file. @@ -147,8 +370,8 @@ def pathToTestData(relative_path): return os.path.join(this_file_without_ext + "_data", relative_path) -def readTestData(relative_path): - with open(pathToTestData(relative_path), "r") as f: +def read_test_data(relative_path): + with open(path_to_test_data(relative_path), "r", encoding="utf8") as f: return f.read() @@ -156,19 +379,19 @@ class TestSoongConfigBoilerplateInserter(unittest.TestCase): def apply_transformations(self, src, transformations, expected): producer = mm.SdkDistProducer( - subprocess_runner=None, - snapshot_builder=None, + subprocess_runner=mock.Mock(mm.SubprocessRunner), + snapshot_builder=mock.Mock(mm.SnapshotBuilder), script=self._testMethodName, ) with tempfile.TemporaryDirectory() as tmp_dir: path = os.path.join(tmp_dir, "Android.bp") - with open(path, "w") as f: + with open(path, "w", encoding="utf8") as f: f.write(src) mm.apply_transformations(producer, tmp_dir, transformations) - with open(path, "r") as f: + with open(path, "r", encoding="utf8") as f: result = f.read() self.maxDiff = None @@ -181,12 +404,12 @@ class TestSoongConfigBoilerplateInserter(unittest.TestCase): that the correct Soong config module types and variables are used and that it imports the definitions from the correct location. """ - src = readTestData("ipsec_Android.bp.input") + src = read_test_data("ipsec_Android.bp.input") - expected = readTestData("ipsec_Android.bp.expected") + expected = read_test_data("ipsec_Android.bp.expected") module = MAINLINE_MODULES_BY_APEX["com.android.ipsec"] - transformations = module.transformations() + transformations = module.transformations(mm.S) self.apply_transformations(src, transformations, expected) @@ -197,12 +420,30 @@ class TestSoongConfigBoilerplateInserter(unittest.TestCase): common mainline modules. This checks that the ART specific Soong config module types, variable and imports are used. """ - src = readTestData("art_Android.bp.input") + src = read_test_data("art_Android.bp.input") - expected = readTestData("art_Android.bp.expected") + expected = read_test_data("art_Android.bp.expected") module = MAINLINE_MODULES_BY_APEX["com.android.art"] - transformations = module.transformations() + transformations = module.transformations(mm.S) + + self.apply_transformations(src, transformations, expected) + + def test_r_build(self): + """Tests the transformations that are applied for the R build. + + This uses ipsec as an example of a common mainline module. That would + usually apply the mm.SoongConfigBoilerplateInserter transformation but + because this is being run for build R that transformation should not be + applied. + """ + src = read_test_data("ipsec_for_r_Android.bp") + + # There should be no changes made. + expected = src + + module = MAINLINE_MODULES_BY_APEX["com.android.ipsec"] + transformations = module.transformations(mm.R) self.apply_transformations(src, transformations, expected) @@ -210,15 +451,30 @@ class TestSoongConfigBoilerplateInserter(unittest.TestCase): class TestFilterModules(unittest.TestCase): def test_no_filter(self): - modules = mm.filter_modules(mm.MAINLINE_MODULES) - self.assertEqual(modules, mm.MAINLINE_MODULES) + all_modules = mm.MAINLINE_MODULES + mm.BUNDLED_MAINLINE_MODULES + modules = mm.filter_modules(all_modules, None) + self.assertEqual(modules, all_modules) def test_with_filter(self): - os.environ["TARGET_BUILD_APPS"] = "com.android.art" - modules = mm.filter_modules(mm.MAINLINE_MODULES) + modules = mm.filter_modules(mm.MAINLINE_MODULES, "com.android.art") expected = MAINLINE_MODULES_BY_APEX["com.android.art"] self.assertEqual(modules, [expected]) +class TestModuleProperties(unittest.TestCase): + + def test_unbundled(self): + for module in mm.MAINLINE_MODULES: + with self.subTest(module=module): + self.assertFalse(module.is_bundled()) + + def test_bundled(self): + for module in (mm.BUNDLED_MAINLINE_MODULES + + mm.PLATFORM_SDKS_FOR_MAINLINE): + with self.subTest(module=module): + self.assertTrue(module.is_bundled()) + self.assertEqual(module.first_release, mm.LATEST) + + if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/build/mainline_modules_sdks_test_data/art_Android.bp.expected b/build/mainline_modules_sdks_test_data/art_Android.bp.expected index 1d6f5585..135e4e6c 100644 --- a/build/mainline_modules_sdks_test_data/art_Android.bp.expected +++ b/build/mainline_modules_sdks_test_data/art_Android.bp.expected @@ -18,7 +18,7 @@ package { art_prebuilt_prebuilt_bootclasspath_fragment { name: "art-bootclasspath-fragment", - // Do not prefer prebuilt if SOONG_CONFIG_art_module_source_build is true. + // Do not prefer prebuilt if the Soong config variable "source_build" in namespace "art_module" is true. prefer: true, soong_config_variables: { source_build: { @@ -63,7 +63,7 @@ art_prebuilt_prebuilt_bootclasspath_fragment { art_prebuilt_prebuilt_platform_compat_config { name: "libcore-platform-compat-config", - // Do not prefer prebuilt if SOONG_CONFIG_art_module_source_build is true. + // Do not prefer prebuilt if the Soong config variable "source_build" in namespace "art_module" is true. prefer: true, soong_config_variables: { source_build: { @@ -82,7 +82,7 @@ art_prebuilt_prebuilt_platform_compat_config { art_prebuilt_java_import { name: "core-oj", - // Do not prefer prebuilt if SOONG_CONFIG_art_module_source_build is true. + // Do not prefer prebuilt if the Soong config variable "source_build" in namespace "art_module" is true. prefer: true, soong_config_variables: { source_build: { diff --git a/build/mainline_modules_sdks_test_data/google_wifi_for_r_Android.bp b/build/mainline_modules_sdks_test_data/google_wifi_for_r_Android.bp new file mode 100644 index 00000000..11032b2a --- /dev/null +++ b/build/mainline_modules_sdks_test_data/google_wifi_for_r_Android.bp @@ -0,0 +1,46 @@ +// DO NOT EDIT. Auto-generated by the following: +// path/to/mainline_modules_sdks.sh +// +// Copyright (C) 2020 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_sdk_library_import { + name: "framework-wifi", + owner: "google", + prefer: true, + shared_library: false, + apex_available: [ + "com.android.wifi", + "test_com.android.wifi", + ], + public: { + jars: ["public/framework-wifi-stubs.jar"], + current_api: "public/framework-wifi.txt", + removed_api: "public/framework-wifi-removed.txt", + sdk_version: "module_current", + }, + system: { + jars: ["system/framework-wifi-stubs.jar"], + current_api: "system/framework-wifi.txt", + removed_api: "system/framework-wifi-removed.txt", + sdk_version: "module_current", + }, + module_lib: { + jars: ["module-lib/framework-wifi-stubs.jar"], + current_api: "module-lib/framework-wifi.txt", + removed_api: "module-lib/framework-wifi-removed.txt", + sdk_version: "module_current", + }, +} diff --git a/build/mainline_modules_sdks_test_data/ipsec_Android.bp.expected b/build/mainline_modules_sdks_test_data/ipsec_Android.bp.expected index 4586eac6..99640c05 100644 --- a/build/mainline_modules_sdks_test_data/ipsec_Android.bp.expected +++ b/build/mainline_modules_sdks_test_data/ipsec_Android.bp.expected @@ -33,7 +33,7 @@ prebuilt_bootclasspath_fragment { module_prebuilt_bootclasspath_fragment { name: "com.android.ipsec-bootclasspath-fragment", - // Do not prefer prebuilt if SOONG_CONFIG_ANDROID_module_build_from_source is true. + // Do not prefer prebuilt if the Soong config variable "module_build_from_source" in namespace "ANDROID" is true. prefer: true, soong_config_variables: { module_build_from_source: { @@ -94,7 +94,7 @@ java_sdk_library_import { module_java_sdk_library_import { name: "android.net.ipsec.ike", - // Do not prefer prebuilt if SOONG_CONFIG_ANDROID_module_build_from_source is true. + // Do not prefer prebuilt if the Soong config variable "module_build_from_source" in namespace "ANDROID" is true. prefer: true, soong_config_variables: { module_build_from_source: { diff --git a/build/mainline_modules_sdks_test_data/ipsec_for_r_Android.bp b/build/mainline_modules_sdks_test_data/ipsec_for_r_Android.bp new file mode 100644 index 00000000..8effc158 --- /dev/null +++ b/build/mainline_modules_sdks_test_data/ipsec_for_r_Android.bp @@ -0,0 +1,46 @@ +// DO NOT EDIT. Auto-generated by the following: +// path/to/mainline_modules_sdks.sh +// +// Copyright (C) 2020 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_sdk_library_import { + name: "android.net.ipsec.ike", + owner: "google", + prefer: true, + shared_library: true, + apex_available: [ + "com.android.ipsec", + "test_com.android.ipsec", + ], + public: { + jars: ["public/android.net.ipsec.ike-stubs.jar"], + current_api: "public/android.net.ipsec.ike.txt", + removed_api: "public/android.net.ipsec.ike-removed.txt", + sdk_version: "module_current", + }, + system: { + jars: ["system/android.net.ipsec.ike-stubs.jar"], + current_api: "system/android.net.ipsec.ike.txt", + removed_api: "system/android.net.ipsec.ike-removed.txt", + sdk_version: "module_current", + }, + module_lib: { + jars: ["module-lib/android.net.ipsec.ike-stubs.jar"], + current_api: "module-lib/android.net.ipsec.ike.txt", + removed_api: "module-lib/android.net.ipsec.ike-removed.txt", + sdk_version: "module_current", + }, +} diff --git a/javatests/com/android/modules/updatablesharedlibs/Android.bp b/javatests/com/android/modules/updatablesharedlibs/Android.bp index 1c2f7e75..f469f95e 100644 --- a/javatests/com/android/modules/updatablesharedlibs/Android.bp +++ b/javatests/com/android/modules/updatablesharedlibs/Android.bp @@ -36,6 +36,11 @@ java_test_host { "compatibility-host-util", "cts-install-lib-host", "frameworks-base-hostutils", - "truth-prebuilt" + "modules-utils-build-testing", + "truth-prebuilt", + ], + test_suites: [ + "general-tests", + "mts-core", ], } diff --git a/javatests/com/android/modules/updatablesharedlibs/UpdatableSharedLibsTest.java b/javatests/com/android/modules/updatablesharedlibs/UpdatableSharedLibsTest.java index a0fefe4f..05295f61 100644 --- a/javatests/com/android/modules/updatablesharedlibs/UpdatableSharedLibsTest.java +++ b/javatests/com/android/modules/updatablesharedlibs/UpdatableSharedLibsTest.java @@ -26,6 +26,8 @@ import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; import com.android.tradefed.testtype.junit4.DeviceTestRunOptions; import com.android.internal.util.test.SystemPreparer; +import com.android.modules.utils.build.testing.DeviceSdkLevel; + import org.junit.Assert; import org.junit.Rule; import org.junit.Test; @@ -50,6 +52,7 @@ public class UpdatableSharedLibsTest extends BaseHostJUnit4Test { if (!getDevice().isAdbRoot()) { getDevice().enableAdbRoot(); } + assumeTrue("Device needs to run on at least T", isAtLeastT()); assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported()); assumeTrue("Device requires root", getDevice().isAdbRoot()); @@ -80,4 +83,9 @@ public class UpdatableSharedLibsTest extends BaseHostJUnit4Test { + "unavailable shared library " + "com.android.modules.updatablesharedlibs.libs.since.t"); } + + protected boolean isAtLeastT() throws Exception { + DeviceSdkLevel deviceSdkLevel = new DeviceSdkLevel(getDevice()); + return deviceSdkLevel.isDeviceAtLeastT(); + } } diff --git a/proto/sdk.proto b/proto/sdk.proto index 4fddf8df..850b31b4 100644 --- a/proto/sdk.proto +++ b/proto/sdk.proto @@ -38,6 +38,11 @@ enum SdkModule { // S modules ART = 8; SCHEDULING = 9; + + // T modules + AD_SERVICES = 11; + APPSEARCH = 12; + ON_DEVICE_PERSONALIZATION = 13; } // A single extension version. diff --git a/sdk/Android.bp b/sdk/Android.bp index 8606d1d7..2fda6f90 100644 --- a/sdk/Android.bp +++ b/sdk/Android.bp @@ -14,5 +14,4 @@ build = [ "ModuleDefaults.bp", - "StubLibraries.bp", ] diff --git a/sdk/ModuleDefaults.bp b/sdk/ModuleDefaults.bp index 340c6ee9..cf1b417d 100644 --- a/sdk/ModuleDefaults.bp +++ b/sdk/ModuleDefaults.bp @@ -132,8 +132,6 @@ java_defaults { ":__subpackages__", "//frameworks/base/apex:__subpackages__", "//frameworks/base/libs/hwui", - // TODO(b/208914639): remove after moving files to packages/modules/Connectivity - "//frameworks/base/packages/ConnectivityT:__subpackages__", "//frameworks/base/wifi", "//packages/modules:__subpackages__", "//packages/providers/MediaProvider:__subpackages__", @@ -193,3 +191,36 @@ java_defaults { dir: "apistubs/android/system-server", }, } + +// These apex_defaults serve as a common place to add properties which should +// affect all mainline modules. +apex_defaults { + name: "q-launched-apex-module", + min_sdk_version: "29", + updatable: true, + defaults_visibility: ["//visibility:public"], +} + +apex_defaults { + name: "r-launched-apex-module", + min_sdk_version: "30", + updatable: true, + defaults_visibility: ["//visibility:public"], +} + +apex_defaults { + name: "s-launched-apex-module", + min_sdk_version: "31", + updatable: true, + defaults_visibility: [ + "//art:__subpackages__", + "//packages/modules:__subpackages__", + ], +} + +apex_defaults { + name: "t-launched-apex-module", + min_sdk_version: "Tiramisu", + updatable: true, + defaults_visibility: ["//packages/modules:__subpackages__"], +} diff --git a/sdk/StubLibraries.bp b/sdk/StubLibraries.bp deleted file mode 100644 index f2cfae1a..00000000 --- a/sdk/StubLibraries.bp +++ /dev/null @@ -1,61 +0,0 @@ -// 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. - -java_defaults { - name: "android.jar_defaults", - sdk_version: "none", - system_modules: "none", - java_version: "1.8", - compile_dex: true, - defaults_visibility: ["//frameworks/base"], - visibility: ["//visibility:public"], -} - -java_library_static { - name: "android_30xcurrent", - static_libs: [ - "sdk_public_30_android-non-updatable", // Prebuilt non-updatable 30 stub. - "private-stub-annotations-jar", - - // Public stubs for BCP modules in Android R built from source - "conscrypt.module.public.api.stubs", - "framework-media.stubs", - "framework-mediaprovider.stubs", - "framework-permission.stubs", - "framework-sdkextensions.stubs", - "framework-statsd.stubs", - "framework-tethering.stubs", - "framework-wifi.stubs", - ], - defaults: ["android.jar_defaults"], -} - -java_library_static { - name: "android_system_30xcurrent", - static_libs: [ - "sdk_system_30_android-non-updatable", // Prebuilt non-updatable 30 stub. - "private-stub-annotations-jar", - - // System stubs for BCP modules in Android R built from source - "conscrypt.module.public.api.stubs", // Only has public stubs - "framework-media.stubs.system", - "framework-mediaprovider.stubs.system", - "framework-permission.stubs.system", - "framework-sdkextensions.stubs.system", - "framework-statsd.stubs.system", - "framework-tethering.stubs.system", - "framework-wifi.stubs.system", - ], - defaults: ["android.jar_defaults"], -} diff --git a/tools/Android.bp b/tools/Android.bp index 642c2f8a..1bb33fa9 100644 --- a/tools/Android.bp +++ b/tools/Android.bp @@ -65,9 +65,12 @@ prebuilt_etc { "//art:__subpackages__", "//external/conscrypt:__subpackages__", "//frameworks/av/apex:__subpackages__", + "//packages/modules/AdServices:__subpackages__", + "//packages/modules/AppSearch:__subpackages__", "//packages/modules/Connectivity:__subpackages__", "//packages/modules/IPsec/apex:__subpackages__", "//packages/modules/Permission:__subpackages__", + "//packages/modules/OnDevicePersonalization:__subpackages__", "//packages/modules/Scheduling:__subpackages__", "//packages/modules/SdkExtensions:__subpackages__", "//packages/modules/StatsD:__subpackages__", diff --git a/tools/finalize_sdk.py b/tools/finalize_sdk.py index c862d892..84fd762e 100755 --- a/tools/finalize_sdk.py +++ b/tools/finalize_sdk.py @@ -1,19 +1,27 @@ #!/usr/bin/python3 import argparse +import glob import os import re +import shutil import subprocess import sys import tempfile import zipfile from collections import defaultdict +from pathlib import Path # See go/fetch_artifact for details on this script. FETCH_ARTIFACT = '/google/data/ro/projects/android/fetch_artifact' -BUILD_TARGET = 'mainline_modules-userdebug' -ARTIFACT_PATTERN = 'mainline-sdks/*-%d.zip' +COMPAT_REPO = Path('prebuilts/sdk') +# This build target is used when fetching from a train build (TXXXXXXXX) +BUILD_TARGET_TRAIN = 'train_build' +# This build target is used when fetching from a non-train build (XXXXXXXX) +BUILD_TARGET_CONTINUOUS = 'mainline_modules-user' +# The glob of sdk artifacts to fetch +ARTIFACT_PATTERN = 'mainline-sdks/current/{module_name}/sdk/*.zip' COMMIT_TEMPLATE = """Finalize artifacts for extension SDK %d Import from build id %s. @@ -29,14 +37,14 @@ def fail(*args, **kwargs): sys.exit(1) def fetch_artifacts(target, build_id, artifact_path): - tmpdir = tempfile.TemporaryDirectory().name - os.mkdir(tmpdir) + tmpdir = Path(tempfile.TemporaryDirectory().name) + tmpdir.mkdir() print('Fetching %s from %s ...' % (artifact_path, target)) fetch_cmd = [FETCH_ARTIFACT] fetch_cmd.extend(['--bid', str(build_id)]) fetch_cmd.extend(['--target', target]) fetch_cmd.append(artifact_path) - fetch_cmd.append(tmpdir) + fetch_cmd.append(str(tmpdir)) print("Running: " + ' '.join(fetch_cmd)) try: subprocess.check_output(fetch_cmd, stderr=subprocess.STDOUT) @@ -47,8 +55,8 @@ def fetch_artifacts(target, build_id, artifact_path): def repo_for_sdk(filename): module = filename.split('-')[0] target_dir = '' - if module == 'media': return 'prebuilts/module_sdk/Media' - if module == 'tethering': return 'prebuilts/module_sdk/Connectivity' + if module == 'media': return Path('prebuilts/module_sdk/Media') + if module == 'tethering': return Path('prebuilts/module_sdk/Connectivity') for dir in os.listdir('prebuilts/module_sdk/'): if module.lower() in dir.lower(): if target_dir: @@ -57,7 +65,7 @@ def repo_for_sdk(filename): if not target_dir: fail('Could not find a target dir for %s' % filename) - return 'prebuilts/module_sdk/%s' % target_dir + return Path('prebuilts/module_sdk/%s' % target_dir) def dir_for_sdk(filename, version): base = str(version) @@ -74,35 +82,56 @@ parser = argparse.ArgumentParser(description=('Finalize an extension SDK with pr parser.add_argument('-f', '--finalize_sdk', type=int, required=True, help='The numbered SDK to finalize.') parser.add_argument('-b', '--bug', type=int, required=True, help='The bug number to add to the commit message.') parser.add_argument('-a', '--amend_last_commit', action="store_true", help='Amend current HEAD commits instead of making new commits.') +parser.add_argument('-m', '--modules', action='append', help='Modules to include. Can be provided multiple times, or not at all for all modules.') parser.add_argument('bid', help='Build server build ID') args = parser.parse_args() +build_target = BUILD_TARGET_TRAIN if args.bid[0] == 'T' else BUILD_TARGET_CONTINUOUS branch_name = 'finalize-%d' % args.finalize_sdk -cmdline = " ".join(filter(lambda x: x not in ['-a', '--amend_last_commit'], sys.argv)) +cmdline = " ".join([x for x in sys.argv if x not in ['-a', '--amend_last_commit']]) commit_message = COMMIT_TEMPLATE % (args.finalize_sdk, args.bid, cmdline, args.bug) - -tmpdir = fetch_artifacts(BUILD_TARGET, args.bid, ARTIFACT_PATTERN % args.finalize_sdk) - -created_dirs = defaultdict(list) - -for f in os.listdir(tmpdir): - repo = repo_for_sdk(f) - dir = dir_for_sdk(f, args.finalize_sdk) - target_dir = os.path.join(repo, dir) - if os.path.isfile(target_dir): - print('Removing existing dir %s' % target_dir) - shutil.rmtree(target_dir) - with zipfile.ZipFile(os.path.join(tmpdir, f)) as zipFile: - zipFile.extractall(target_dir) - - print('Created %s' % target_dir) - created_dirs[repo].append(dir) +module_names = args.modules +if not module_names: + module_names = ['*'] + +compat_dir = COMPAT_REPO.joinpath('extensions/%d' % args.finalize_sdk) +if compat_dir.is_dir(): + print('Removing existing dir %s' % compat_dir) + shutil.rmtree(compat_dir) + +created_dirs = defaultdict(set) +for m in module_names: + tmpdir = fetch_artifacts(build_target, args.bid, ARTIFACT_PATTERN.format(module_name=m)) + for f in tmpdir.iterdir(): + repo = repo_for_sdk(f.name) + dir = dir_for_sdk(f.name, args.finalize_sdk) + target_dir = repo.joinpath(dir) + if target_dir.is_dir(): + print('Removing existing dir %s' % target_dir) + shutil.rmtree(target_dir) + with zipfile.ZipFile(tmpdir.joinpath(f)) as zipFile: + zipFile.extractall(target_dir) + + # Just capture the artifacts, not the bp files of finalized versions + os.remove(target_dir.joinpath('Android.bp')) + + print('Created %s' % target_dir) + created_dirs[repo].add(dir) + + # Copy api txt files to compat tracking dir + txt_files = [Path(p) for p in glob.glob(os.path.join(target_dir, 'sdk_library/*/*.txt'))] + for txt_file in txt_files: + api_type = txt_file.parts[-2] + dest_dir = compat_dir.joinpath(api_type, 'api') + os.makedirs(dest_dir, exist_ok = True) + shutil.copy(txt_file, dest_dir) + created_dirs[COMPAT_REPO].add(dest_dir.relative_to(COMPAT_REPO)) subprocess.check_output(['repo', 'start', branch_name] + list(created_dirs.keys())) print('Running git commit') for repo in created_dirs: - git = ['git', '-C', repo] - subprocess.check_output(git + ['add'] + created_dirs[repo]) + git = ['git', '-C', str(repo)] + subprocess.check_output(git + ['add'] + list(created_dirs[repo])) if args.amend_last_commit: change_id = '\n' + re.search(r'Change-Id: [^\\n]+', str(subprocess.check_output(git + ['log', '-1']))).group(0) subprocess.check_output(git + ['commit', '--amend', '-m', commit_message + change_id]) |