aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRomain Jobredeaux <jobredeaux@google.com>2023-10-09 17:16:34 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2023-10-09 17:16:34 +0000
commitc86e585873865df43f29159d6877b994d0969de3 (patch)
treea58049c9682d6fd38e8408479340bf3911b87515
parent56ecb1810328119a93153b8319cd687ae525463e (diff)
parent3956589553f0a39826ee53bfdb52ccf49d53c283 (diff)
downloadbazelbuild-rules_android-c86e585873865df43f29159d6877b994d0969de3.tar.gz
Merge remote-tracking branch 'aosp/upstream-main' into HEAD am: 39292a3354 am: 3956589553
Original change: https://android-review.googlesource.com/c/platform/external/bazelbuild-rules_android/+/2777173 Change-Id: I4c3131a59187cf7600bcfb7425a7b28aa8e1b078 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--METADATA4
-rw-r--r--MODULE.bazel3
-rw-r--r--WORKSPACE7
-rw-r--r--defs.bzl18
-rw-r--r--defs_dev.bzl31
-rw-r--r--go.mod3
-rw-r--r--go.sum2
-rw-r--r--kokoro/presubmit/presubmit_main.sh8
-rw-r--r--mobile_install/dependency_map.bzl22
-rw-r--r--mobile_install/tools.bzl8
-rw-r--r--prereqs.bzl43
-rw-r--r--rules/BUILD1
-rw-r--r--rules/aar_import/impl.bzl2
-rw-r--r--rules/acls.bzl58
-rw-r--r--rules/acls/min_sdk_floors.bzl (renamed from rules/acls/enforce_min_sdk_floor_rollout.bzl)20
-rw-r--r--rules/android_application/android_application_rule.bzl4
-rw-r--r--rules/android_binary_internal/attrs.bzl4
-rw-r--r--rules/android_binary_internal/impl.bzl68
-rw-r--r--rules/android_binary_internal/r8.bzl1
-rw-r--r--rules/android_library/impl.bzl2
-rw-r--r--rules/android_library/rule.bzl6
-rw-r--r--rules/android_local_test/impl.bzl6
-rw-r--r--rules/android_neverlink_aspect.bzl4
-rw-r--r--rules/android_sandboxed_sdk/android_binary_with_sandboxed_sdks_macro.bzl70
-rw-r--r--rules/android_sdk_repository/helper.bzl45
-rw-r--r--rules/attrs.bzl6
-rw-r--r--rules/bundletool.bzl72
-rw-r--r--rules/busybox.bzl5
-rw-r--r--rules/dex.bzl16
-rw-r--r--rules/dex_desugar_aspect.bzl9
-rw-r--r--rules/instrumented_app_info_aspect.bzl26
-rw-r--r--rules/native_deps.bzl27
-rw-r--r--rules/proguard.bzl48
-rw-r--r--rules/resources.bzl19
-rw-r--r--rules/sandboxed_sdk_toolbox.bzl14
-rw-r--r--src/tools/ak/rjar/rjar.go5
-rw-r--r--src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/config/SdkModulesConfigUtils.java45
-rw-r--r--src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/BUILD (renamed from src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/config/BUILD)5
-rw-r--r--src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/SdkInfo.java61
-rw-r--r--src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/SdkInfoReader.java73
-rw-r--r--src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/AndroidManifestWriter.java12
-rw-r--r--src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/BUILD2
-rw-r--r--src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/GenerateSdkDependenciesManifestCommand.java31
-rw-r--r--src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/BUILD12
-rw-r--r--src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/GenerateSdkDependenciesManifestCommandTest.java47
-rw-r--r--src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/testdata/com.example.archivedsdkmetadata.json11
-rw-r--r--src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/testdata/expected_manifest_with_archived_sdk.xml7
-rw-r--r--src/tools/mi/deployment_oss/BUILD36
-rw-r--r--src/tools/mi/deployment_oss/deploy.go64
-rw-r--r--src/tools/mi/deployment_oss/deploy_binary.go217
-rw-r--r--test/rules/android_binary_internal/r8_integration/java/com/basicapp/BUILD12
-rw-r--r--test/rules/android_library_extensibility/BUILD28
-rw-r--r--test/rules/android_library_extensibility/custom_android_library.bzl86
-rw-r--r--test/rules/android_library_extensibility/test.bzl41
-rw-r--r--test/rules/android_local_test/BUILD69
-rw-r--r--test/rules/android_local_test/EmptyTest.java25
-rw-r--r--test/rules/android_local_test/integration_test_stub_script.sh24
-rw-r--r--test/rules/android_local_test/java/com/starlark_resources/AndroidManifest.xml7
-rw-r--r--test/rules/android_local_test/java/com/starlark_resources/BUILD177
-rw-r--r--test/rules/android_local_test/java/com/starlark_resources/SampleTest.java43
-rw-r--r--test/rules/android_local_test/java/com/starlark_resources/SampleTestMultipleDeps.java45
-rw-r--r--test/rules/android_local_test/java/com/starlark_resources/SampleTestNeverlinkDep.java51
-rw-r--r--test/rules/android_local_test/java/com/starlark_resources/another_res/values/strings.xml4
-rw-r--r--test/rules/android_local_test/java/com/starlark_resources/assets/bar.txt1
-rw-r--r--test/rules/android_local_test/java/com/starlark_resources/assets/foo.txt1
-rw-r--r--test/rules/android_local_test/java/com/starlark_resources/res/values/strings.xml4
-rw-r--r--test/rules/android_local_test/java_launcher_integration_test.bzl64
-rw-r--r--test/rules/android_local_test/java_launcher_test.bzl50
-rw-r--r--test/rules/android_local_test/non_java/AndroidManifest.xml7
-rw-r--r--test/rules/android_local_test/non_java/BUILD51
-rw-r--r--test/rules/android_local_test/non_java/SampleTest.java43
-rw-r--r--test/rules/android_local_test/non_java/assets/bar.txt1
-rw-r--r--test/rules/android_local_test/non_java/res/values/strings.xml4
-rw-r--r--test/rules/android_local_test/test.bzl117
-rw-r--r--test/rules/android_sdk_repository/test_lib.sh15
-rw-r--r--toolchains/android/toolchain.bzl1
-rw-r--r--tools/android/BUILD13
77 files changed, 1963 insertions, 331 deletions
diff --git a/METADATA b/METADATA
index 325190d..450f266 100644
--- a/METADATA
+++ b/METADATA
@@ -12,7 +12,7 @@ third_party {
type: GIT
value: "https://github.com/bazelbuild/rules_android"
}
- version: "d1dca942348973d99c9e33247f17fb5f1ef92732"
- last_upgrade_date { year: 2023 month: 7 day: 25 }
+ version: "b1ad8136600931878dba61dbb28068bde5d5ed84"
+ last_upgrade_date { year: 2023 month: 10 day: 6 }
license_type: NOTICE
}
diff --git a/MODULE.bazel b/MODULE.bazel
index 82c2a0d..2b38cc9 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -13,7 +13,7 @@ use_repo(rules_java_toolchains, "remote_java_tools")
bazel_dep(name = "protobuf", version = "3.19.0", repo_name = "com_google_protobuf")
bazel_dep(name = "rules_jvm_external", version = "4.5")
bazel_dep(name = "bazel_skylib", version = "1.0.3")
-bazel_dep(name = "rules_robolectric", version = "4.10")
+bazel_dep(name = "rules_robolectric", version = "4.10", repo_name = "robolectric")
register_toolchains("//toolchains/android:all")
@@ -32,6 +32,7 @@ go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//:go.mod")
use_repo(
go_deps,
+ "com_github_golang_glog",
"com_github_google_go_cmp",
"org_golang_google_protobuf",
"org_golang_x_sync",
diff --git a/WORKSPACE b/WORKSPACE
index fd043f2..c8a94bc 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -19,12 +19,15 @@ maybe(
android_sdk_supplemental_repository(name = "androidsdk-supplemental")
load("prereqs.bzl", "rules_android_prereqs")
-rules_android_prereqs()
-load("defs.bzl", "rules_android_workspace")
+rules_android_prereqs(dev_mode = True)
+
+load("defs_dev.bzl", "rules_android_workspace")
rules_android_workspace()
register_toolchains("//toolchains/android:all")
+
register_toolchains("//toolchains/android_sdk:all")
+
register_toolchains("//toolchains/emulator:all")
diff --git a/defs.bzl b/defs.bzl
index 4e91209..5ae144a 100644
--- a/defs.bzl
+++ b/defs.bzl
@@ -16,11 +16,9 @@
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
-load("@cgrindel_bazel_starlib//:deps.bzl", "bazel_starlib_dependencies")
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@robolectric//bazel:robolectric.bzl", "robolectric_repositories")
-load("@rules_bazel_integration_test//bazel_integration_test:defs.bzl", "bazel_binaries")
load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
load("@rules_jvm_external//:defs.bzl", "maven_install")
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
@@ -83,6 +81,13 @@ def rules_android_workspace():
version = "v0.0.0-20210220032951-036812b2e83c",
)
+ go_repository(
+ name = "com_github_golang_glog",
+ importpath = "github.com/golang/glog",
+ version = "v1.1.2",
+ sum = "h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=",
+ )
+
robolectric_repositories()
rules_java_dependencies()
@@ -92,12 +97,3 @@ def rules_android_workspace():
rules_proto_toolchains()
py_repositories()
-
- # Integration test setup
- bazel_starlib_dependencies()
-
- bazel_binaries(
- versions = [
- "last_green",
- ],
- )
diff --git a/defs_dev.bzl b/defs_dev.bzl
new file mode 100644
index 0000000..7c31efe
--- /dev/null
+++ b/defs_dev.bzl
@@ -0,0 +1,31 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+"""Workspace setup macro for rules_android development."""
+
+load("@cgrindel_bazel_starlib//:deps.bzl", "bazel_starlib_dependencies")
+load("@rules_bazel_integration_test//bazel_integration_test:defs.bzl", "bazel_binaries")
+load(":defs.bzl", non_dev_workspace = "rules_android_workspace")
+
+def rules_android_workspace():
+ non_dev_workspace()
+
+ # Integration test setup
+ bazel_starlib_dependencies()
+
+ bazel_binaries(
+ versions = [
+ "last_green",
+ ],
+ )
diff --git a/go.mod b/go.mod
index 68f0c90..bd31721 100644
--- a/go.mod
+++ b/go.mod
@@ -1,9 +1,10 @@
module github.com/bazelbuild/rules_android
-go 1.18
+go 1.19
require (
github.com/google/go-cmp v0.5.9
+ github.com/golang/glog v1.1.2
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
google.golang.org/protobuf v1.28.1
)
diff --git a/go.sum b/go.sum
index 23ba436..7c6ca1b 100644
--- a/go.sum
+++ b/go.sum
@@ -1,3 +1,5 @@
+github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=
+github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
diff --git a/kokoro/presubmit/presubmit_main.sh b/kokoro/presubmit/presubmit_main.sh
index ceb4bd9..c47237b 100644
--- a/kokoro/presubmit/presubmit_main.sh
+++ b/kokoro/presubmit/presubmit_main.sh
@@ -98,14 +98,18 @@ function main() {
cd "${KOKORO_ARTIFACTS_DIR}/git/rules_android"
# Fetch all external deps; should reveal any bugs related to external dep
- # references.
- "$bazel" aquery 'deps(...)' --noenable_bzlmod 2>&1 > /dev/null
+ # references. First run this query with bzlmod enabled to catch missing
+ # bzlmod deps.
+ "$bazel" aquery 'deps(...)' --enable_bzlmod > /dev/null
+ # Perform the same aquery with bzlmod disabled to sniff out WORKSPACE issues
+ "$bazel" aquery 'deps(...)' --noenable_bzlmod > /dev/null
"$bazel" test "${COMMON_ARGS[@]}" //src/common/golang/... \
//src/tools/ak/... \
//src/tools/javatests/... \
//src/tools/jdeps/... \
//src/tools/java/... \
+ //src/tools/mi/... \
//test/...
# Go to basic app workspace in the source tree
diff --git a/mobile_install/dependency_map.bzl b/mobile_install/dependency_map.bzl
index 2769a90..7b90cd2 100644
--- a/mobile_install/dependency_map.bzl
+++ b/mobile_install/dependency_map.bzl
@@ -16,37 +16,37 @@
versioned_deps = struct(
mi_shell_app = struct(
- head = "//tools/android:fail",
+ head = "//tools/android:gen_fail",
),
android_kit = struct(
head = "//src/tools/ak",
),
bootstraper = struct(
- head = "//tools/android:fail",
+ head = "//tools/android:gen_fail",
),
deploy = struct(
- head = "//src/tools/mi/deployment:deploy_binary",
+ head = "//src/tools/mi/deployment_oss:deploy_binary",
),
deploy_info = struct(
- head = "//src/tools/mi/deploy_info:deploy_info",
+ head = "//tools/android:gen_fail",
),
forwarder = struct(
- head = "//tools/android:fail",
+ head = "//tools/android:gen_fail",
),
jar_tool = struct(
head = "@bazel_tools//tools/jdk:JavaBuilder_deploy.jar",
),
make_sync = struct(
- head = "//src/tools/mi/app_info:make_sync",
+ head = "//tools/android:gen_fail",
),
merge_syncs = struct(
- head = "//src/tools/mi/workspace:merge_syncs",
+ head = "//tools/android:gen_fail",
),
pack_dexes = struct(
- head = "//src/tools/mi/workspace:pack_dexes",
+ head = "//tools/android:gen_fail",
),
pack_generic = struct(
- head = "//src/tools/mi/workspace:pack_generic",
+ head = "//tools/android:gen_fail",
),
res_v3_dummy_manifest = struct(
head = "//rules:res_v3_dummy_AndroidManifest.xml",
@@ -55,9 +55,9 @@ versioned_deps = struct(
head = "//rules:res_v3_dummy_R.txt",
),
resource_extractor = struct(
- head = "//src/tools/resource_extractor:main",
+ head = "//tools/android:gen_fail",
),
sync_merger = struct(
- head = "//src/tools/mi/app_info:sync_merger",
+ head = "//tools/android:gen_fail",
),
)
diff --git a/mobile_install/tools.bzl b/mobile_install/tools.bzl
index 5086779..70c49c5 100644
--- a/mobile_install/tools.bzl
+++ b/mobile_install/tools.bzl
@@ -26,7 +26,7 @@ TOOL_ATTRS = dict(
# use dummy libs.
_android_sdk = attr.label(
default = Label(
- "@androidsdk//:sdk",
+ "//tools/android:android_jar",
),
allow_files = True,
cfg = "target",
@@ -37,14 +37,14 @@ TOOL_ATTRS = dict(
),
),
_studio_deployer = attr.label(
- default = "@androidsdk//:fail", # TODO(#119): Studio deployer jar to be released
+ default = "//tools/android:gen_fail", # TODO(#119): Studio deployer jar to be released
allow_single_file = True,
cfg = "exec",
executable = True,
),
_mi_shell_dummy_native_libs = attr.label(
default = Label(
- "@androidsdk//:fail", # FIXME: Unused internally
+ "//tools/android:gen_fail", # FIXME: Unused internally
),
allow_single_file = True,
cfg = "target",
@@ -91,7 +91,7 @@ TOOL_ATTRS = dict(
executable = True,
),
_d8 = attr.label(
- default = Label("@bazel_tools//src/tools/android/java/com/google/devtools/build/android/r8:r8"),
+ default = Label("//tools/android:d8"),
allow_files = True,
cfg = "exec",
executable = True,
diff --git a/prereqs.bzl b/prereqs.bzl
index 2c70587..893fb43 100644
--- a/prereqs.bzl
+++ b/prereqs.bzl
@@ -17,7 +17,7 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
-def rules_android_prereqs():
+def rules_android_prereqs(dev_mode = False):
"""Downloads prerequisite repositories for rules_android."""
maybe(
http_archive,
@@ -87,9 +87,9 @@ def rules_android_prereqs():
maybe(
http_archive,
name = "robolectric",
- urls = ["https://github.com/robolectric/robolectric-bazel/archive/4.9.2.tar.gz"],
- strip_prefix = "robolectric-bazel-4.9.2",
- sha256 = "7e007fcfdca7b7228cb4de72707e8b317026ea95000f963e91d5ae365be52d0d",
+ urls = ["https://github.com/robolectric/robolectric-bazel/archive/4.10.3.tar.gz"],
+ strip_prefix = "robolectric-bazel-4.10.3",
+ sha256 = "1b199a932cbde4af728dd8275937091adbb89a4bf63d326de49e6d0a42e723bf",
)
maybe(
@@ -133,20 +133,21 @@ def rules_android_prereqs():
sha256 = "84aec9e21cc56fbc7f1335035a71c850d1b9b5cc6ff497306f84cced9a769841",
)
- maybe(
- http_archive,
- name = "rules_bazel_integration_test",
- sha256 = "d6dada79939533a8127000d2aafa125f29a4a97f720e01c050fdeb81b1080b08",
- urls = [
- "https://github.com/bazel-contrib/rules_bazel_integration_test/releases/download/v0.17.0/rules_bazel_integration_test.v0.17.0.tar.gz",
- ],
- )
-
- maybe(
- http_archive,
- name = "cgrindel_bazel_starlib",
- sha256 = "a8d25340956b429b56302d3fd702bb3df8b3a67db248dd32b3084891ad497964",
- urls = [
- "https://github.com/cgrindel/bazel-starlib/releases/download/v0.17.0/bazel-starlib.v0.17.0.tar.gz",
- ],
- )
+ if dev_mode:
+ maybe(
+ http_archive,
+ name = "rules_bazel_integration_test",
+ sha256 = "d6dada79939533a8127000d2aafa125f29a4a97f720e01c050fdeb81b1080b08",
+ urls = [
+ "https://github.com/bazel-contrib/rules_bazel_integration_test/releases/download/v0.17.0/rules_bazel_integration_test.v0.17.0.tar.gz",
+ ],
+ )
+
+ maybe(
+ http_archive,
+ name = "cgrindel_bazel_starlib",
+ sha256 = "a8d25340956b429b56302d3fd702bb3df8b3a67db248dd32b3084891ad497964",
+ urls = [
+ "https://github.com/cgrindel/bazel-starlib/releases/download/v0.17.0/bazel-starlib.v0.17.0.tar.gz",
+ ],
+ )
diff --git a/rules/BUILD b/rules/BUILD
index 467072b..d907612 100644
--- a/rules/BUILD
+++ b/rules/BUILD
@@ -33,6 +33,7 @@ bzl_library(
"common.bzl",
"data_binding.bzl",
"idl.bzl",
+ "instrumented_app_info_aspect.bzl",
"intellij.bzl",
"java.bzl",
"migration_tag_DONOTUSE.bzl",
diff --git a/rules/aar_import/impl.bzl b/rules/aar_import/impl.bzl
index 0b149bb..c80d618 100644
--- a/rules/aar_import/impl.bzl
+++ b/rules/aar_import/impl.bzl
@@ -475,7 +475,7 @@ def impl(ctx):
manifest_ctx = _resources.bump_min_sdk(
ctx,
manifest = android_manifest,
- floor = _resources.DEPOT_MIN_SDK_FLOOR if _acls.in_enforce_min_sdk_floor_rollout(str(ctx.label)) else 0,
+ floor = _acls.get_min_sdk_floor(str(ctx.label)),
enforce_min_sdk_floor_tool = _get_android_toolchain(ctx).enforce_min_sdk_floor_tool.files_to_run,
)
diff --git a/rules/acls.bzl b/rules/acls.bzl
index 858ef07..edef667 100644
--- a/rules/acls.bzl
+++ b/rules/acls.bzl
@@ -33,56 +33,62 @@ load("//rules/acls:aar_import_exports_r_java.bzl", "AAR_IMPORT_EXPORTS_R_JAVA")
load("//rules/acls:aar_propagate_resources.bzl", "AAR_PROPAGATE_RESOURCES_FALLBACK", "AAR_PROPAGATE_RESOURCES_ROLLOUT")
load("//rules/acls:ait_install_snapshots.bzl", "APP_INSTALLATION_SNAPSHOT", "APP_INSTALLATION_SNAPSHOT_FALLBACK")
load("//rules/acls:allow_resource_conflicts.bzl", "ALLOW_RESOURCE_CONFLICTS")
+load("//rules/acls:android_apk_to_bundle_features_lockdown.bzl", "ANDROID_APK_TO_BUNDLE_FEATURES")
load("//rules/acls:android_archive_dogfood.bzl", "ANDROID_ARCHIVE_DOGFOOD")
load("//rules/acls:android_archive_duplicate_class_allowlist.bzl", "ANDROID_ARCHIVE_DUPLICATE_CLASS_ALLOWLIST")
load("//rules/acls:android_archive_excluded_deps_denylist.bzl", "ANDROID_ARCHIVE_EXCLUDED_DEPS_DENYLIST")
load("//rules/acls:android_archive_exposed_package_allowlist.bzl", "ANDROID_ARCHIVE_EXPOSED_PACKAGE_ALLOWLIST")
-load("//rules/acls:android_test_lockdown.bzl", "ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS", "ANDROID_TEST_LOCKDOWN_TARGETS")
-load("//rules/acls:android_device_plugin_rollout.bzl", "ANDROID_DEVICE_PLUGIN_FALLBACK", "ANDROID_DEVICE_PLUGIN_ROLLOUT")
-load("//rules/acls:android_instrumentation_binary_starlark_resources.bzl", "ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK", "ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT")
+load("//rules/acls:android_binary_min_sdk_version_attribute.bzl", "ANDROID_BINARY_MIN_SDK_VERSION_ATTRIBUTE_ALLOWLIST")
+load("//rules/acls:android_binary_raw_access_to_resource_paths_allowlist.bzl", "ANDROID_BINARY_RAW_ACCESS_TO_RESOURCE_PATHS_ALLOWLIST")
+load("//rules/acls:android_binary_resource_name_obfuscation_opt_out_allowlist.bzl", "ANDROID_BINARY_RESOURCE_NAME_OBFUSCATION_OPT_OUT_ALLOWLIST")
+load("//rules/acls:android_binary_starlark_dex_desugar_proguard.bzl", "ANDROID_BINARY_STARLARK_DEX_DESUGAR_PROGUARD_FALLBACK", "ANDROID_BINARY_STARLARK_DEX_DESUGAR_PROGUARD_ROLLOUT")
load("//rules/acls:android_binary_starlark_javac.bzl", "ANDROID_BINARY_STARLARK_JAVAC_FALLBACK", "ANDROID_BINARY_STARLARK_JAVAC_ROLLOUT")
load("//rules/acls:android_binary_starlark_split_transition.bzl", "ANDROID_BINARY_STARLARK_SPLIT_TRANSITION_FALLBACK", "ANDROID_BINARY_STARLARK_SPLIT_TRANSITION_ROLLOUT")
load("//rules/acls:android_binary_with_sandboxed_sdks_allowlist.bzl", "ANDROID_BINARY_WITH_SANDBOXED_SDKS_ALLOWLIST")
+load("//rules/acls:android_build_stamping_rollout.bzl", "ANDROID_BUILD_STAMPING_FALLBACK", "ANDROID_BUILD_STAMPING_ROLLOUT")
+load("//rules/acls:android_device_plugin_rollout.bzl", "ANDROID_DEVICE_PLUGIN_FALLBACK", "ANDROID_DEVICE_PLUGIN_ROLLOUT")
load("//rules/acls:android_feature_splits_dogfood.bzl", "ANDROID_FEATURE_SPLITS_DOGFOOD")
+load("//rules/acls:android_instrumentation_binary_starlark_resources.bzl", "ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_FALLBACK", "ANDROID_INSTRUMENTATION_BINARY_STARLARK_RESOURCES_ROLLOUT")
+load("//rules/acls:android_instrumentation_test_manifest_check_rollout.bzl", "ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_FALLBACK", "ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_ROLLOUT")
+load("//rules/acls:android_instrumentation_test_prebuilt_test_apk.bzl", "ANDROID_INSTRUMENTATION_TEST_PREBUILT_TEST_APK_FALLBACK", "ANDROID_INSTRUMENTATION_TEST_PREBUILT_TEST_APK_ROLLOUT")
load("//rules/acls:android_library_resources_without_srcs.bzl", "ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS", "ANDROID_LIBRARY_RESOURCES_WITHOUT_SRCS_GENERATOR_FUNCTIONS")
load("//rules/acls:android_library_starlark_resource_outputs.bzl", "ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_FALLBACK", "ANDROID_LIBRARY_STARLARK_RESOURCE_OUTPUTS_ROLLOUT")
load("//rules/acls:android_library_use_aosp_aidl_compiler.bzl", "ANDROID_LIBRARY_USE_AOSP_AIDL_COMPILER_ALLOWLIST")
load("//rules/acls:android_lint_checks_rollout.bzl", "ANDROID_LINT_CHECKS_FALLBACK", "ANDROID_LINT_CHECKS_ROLLOUT")
load("//rules/acls:android_lint_rollout.bzl", "ANDROID_LINT_FALLBACK", "ANDROID_LINT_ROLLOUT")
-load("//rules/acls:lint_registry_rollout.bzl", "LINT_REGISTRY_FALLBACK", "LINT_REGISTRY_ROLLOUT")
-load("//rules/acls:android_build_stamping_rollout.bzl", "ANDROID_BUILD_STAMPING_FALLBACK", "ANDROID_BUILD_STAMPING_ROLLOUT")
+load("//rules/acls:android_local_test_jdk_sts_rollout.bzl", "ANDROID_LOCAL_TEST_JDK_STS_FALLBACK", "ANDROID_LOCAL_TEST_JDK_STS_ROLLOUT")
+load("//rules/acls:android_test_lockdown.bzl", "ANDROID_TEST_LOCKDOWN_GENERATOR_FUNCTIONS", "ANDROID_TEST_LOCKDOWN_TARGETS")
+load("//rules/acls:android_test_platform_rollout.bzl", "ANDROID_TEST_PLATFORM_FALLBACK", "ANDROID_TEST_PLATFORM_ROLLOUT")
load("//rules/acls:b122039567.bzl", "B122039567")
load("//rules/acls:b123854163.bzl", "B123854163")
+load("//rules/acls:baseline_profiles_optimizer_integration.bzl", "BASELINE_PROFILES_OPTIMIZER_INTEGRATION")
+load("//rules/acls:baseline_profiles_rollout.bzl", "BASELINE_PROFILES_ROLLOUT")
load("//rules/acls:databinding.bzl", "DATABINDING_ALLOWED", "DATABINDING_DISALLOWED")
load("//rules/acls:dex2oat_opts.bzl", "CAN_USE_DEX2OAT_OPTIONS")
load("//rules/acls:fix_export_exporting_rollout.bzl", "FIX_EXPORT_EXPORTING_FALLBACK", "FIX_EXPORT_EXPORTING_ROLLOUT")
load("//rules/acls:fix_resource_transitivity_rollout.bzl", "FIX_RESOURCE_TRANSITIVITY_FALLBACK", "FIX_RESOURCE_TRANSITIVITY_ROLLOUT")
load("//rules/acls:host_dex2oat_rollout.bzl", "AIT_USE_HOST_DEX2OAT_ROLLOUT", "AIT_USE_HOST_DEX2OAT_ROLLOUT_FALLBACK")
load("//rules/acls:install_apps_in_data.bzl", "INSTALL_APPS_IN_DATA")
+load("//rules/acls:lint_registry_rollout.bzl", "LINT_REGISTRY_FALLBACK", "LINT_REGISTRY_ROLLOUT")
load("//rules/acls:local_test_multi_proto.bzl", "LOCAL_TEST_MULTI_PROTO_PKG")
load("//rules/acls:local_test_rollout.bzl", "LOCAL_TEST_FALLBACK", "LOCAL_TEST_ROLLOUT")
load("//rules/acls:local_test_starlark_resources.bzl", "LOCAL_TEST_STARLARK_RESOURCES_FALLBACK", "LOCAL_TEST_STARLARK_RESOURCES_ROLLOUT")
-load("//rules/acls:android_test_platform_rollout.bzl", "ANDROID_TEST_PLATFORM_FALLBACK", "ANDROID_TEST_PLATFORM_ROLLOUT")
-load("//rules/acls:test_to_instrument_test_rollout.bzl", "TEST_TO_INSTRUMENT_TEST_FALLBACK", "TEST_TO_INSTRUMENT_TEST_ROLLOUT")
+load("//rules/acls:min_sdk_floors.bzl", "MIN_SDK_FLOORS")
load(
"//rules/acls:partial_jetification_targets.bzl",
"PARTIAL_JETIFICATION_TARGETS_FALLBACK",
"PARTIAL_JETIFICATION_TARGETS_ROLLOUT",
)
-load("//rules/acls:android_instrumentation_test_manifest_check_rollout.bzl", "ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_FALLBACK", "ANDROID_INSTRUMENTATION_TEST_MANIFEST_CHECK_ROLLOUT")
-load("//rules/acls:android_instrumentation_test_prebuilt_test_apk.bzl", "ANDROID_INSTRUMENTATION_TEST_PREBUILT_TEST_APK_FALLBACK", "ANDROID_INSTRUMENTATION_TEST_PREBUILT_TEST_APK_ROLLOUT")
-load("//rules/acls:baseline_profiles_rollout.bzl", "BASELINE_PROFILES_ROLLOUT")
-load("//rules/acls:baseline_profiles_optimizer_integration.bzl", "BASELINE_PROFILES_OPTIMIZER_INTEGRATION")
-load("//rules/acls:enforce_min_sdk_floor_rollout.bzl", "ENFORCE_MIN_SDK_FLOOR_FALLBACK", "ENFORCE_MIN_SDK_FLOOR_ROLLOUT")
-load("//rules/acls:android_apk_to_bundle_features_lockdown.bzl", "ANDROID_APK_TO_BUNDLE_FEATURES")
-load("//rules/acls:android_local_test_jdk_sts_rollout.bzl", "ANDROID_LOCAL_TEST_JDK_STS_FALLBACK", "ANDROID_LOCAL_TEST_JDK_STS_ROLLOUT")
-load("//rules/acls:shared_library_resource_linking.bzl", "SHARED_LIBRARY_RESOURCE_LINKING_ALLOWLIST")
-load("//rules/acls:android_binary_starlark_dex_desugar_proguard.bzl", "ANDROID_BINARY_STARLARK_DEX_DESUGAR_PROGUARD_FALLBACK", "ANDROID_BINARY_STARLARK_DEX_DESUGAR_PROGUARD_ROLLOUT")
-load("//rules/acls:android_binary_min_sdk_version_attribute.bzl", "ANDROID_BINARY_MIN_SDK_VERSION_ATTRIBUTE_ALLOWLIST")
-load("//rules/acls:android_binary_raw_access_to_resource_paths_allowlist.bzl", "ANDROID_BINARY_RAW_ACCESS_TO_RESOURCE_PATHS_ALLOWLIST")
-load("//rules/acls:android_binary_resource_name_obfuscation_opt_out_allowlist.bzl", "ANDROID_BINARY_RESOURCE_NAME_OBFUSCATION_OPT_OUT_ALLOWLIST")
load("//rules/acls:proguard_apply_mapping.bzl", "ALLOW_PROGUARD_APPLY_MAPPING")
load("//rules/acls:r8.bzl", "USE_R8")
+load("//rules/acls:shared_library_resource_linking.bzl", "SHARED_LIBRARY_RESOURCE_LINKING_ALLOWLIST")
+load("//rules/acls:test_to_instrument_test_rollout.bzl", "TEST_TO_INSTRUMENT_TEST_FALLBACK", "TEST_TO_INSTRUMENT_TEST_ROLLOUT")
+
+def _get_min_sdk_floor(fqn):
+ for minsdk, package_dict in MIN_SDK_FLOORS_DICT.items():
+ if matches(fqn, package_dict):
+ return minsdk
+ fail("No matching min_sdk_floor for %s" % fqn)
def _in_aar_import_deps_checker(fqn):
return not matches(fqn, AAR_IMPORT_DEPS_CHECKER_FALLBACK_DICT) and matches(fqn, AAR_IMPORT_DEPS_CHECKER_ROLLOUT_DICT)
@@ -213,9 +219,6 @@ def _in_baseline_profiles_rollout(fqn):
def _in_baseline_profiles_optimizer_integration(fqn):
return matches(fqn, BASELINE_PROFILES_OPTIMIZER_INTEGRATION)
-def _in_enforce_min_sdk_floor_rollout(fqn):
- return not matches(fqn, ENFORCE_MIN_SDK_FLOOR_FALLBACK_DICT) and matches(fqn, ENFORCE_MIN_SDK_FLOOR_ROLLOUT_DICT)
-
def _in_android_apk_to_bundle_features(fqn):
return matches(fqn, ANDROID_APK_TO_BUNDLE_FEATURES_DICT)
@@ -250,6 +253,12 @@ def make_dict(lst):
"""Do not use this method outside of acls directory."""
return {t: True for t in lst}
+def make_min_sdk_dict(dict_of_lists):
+ res = {}
+ for k in dict_of_lists.keys():
+ res[k] = make_dict(dict_of_lists[k])
+ return res
+
AAR_IMPORT_DEPS_CHECKER_FALLBACK_DICT = make_dict(AAR_IMPORT_DEPS_CHECKER_FALLBACK)
AAR_IMPORT_DEPS_CHECKER_ROLLOUT_DICT = make_dict(AAR_IMPORT_DEPS_CHECKER_ROLLOUT)
AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST_DICT = make_dict(AAR_IMPORT_EXPLICIT_EXPORTS_MANIFEST)
@@ -313,8 +322,7 @@ ANDROID_INSTRUMENTATION_TEST_PREBUILT_TEST_APK_ROLLOUT_DICT = make_dict(ANDROID_
ANDROID_INSTRUMENTATION_TEST_PREBUILT_TEST_APK_FALLBACK_DICT = make_dict(ANDROID_INSTRUMENTATION_TEST_PREBUILT_TEST_APK_FALLBACK)
BASELINE_PROFILES_ROLLOUT_DICT = make_dict(BASELINE_PROFILES_ROLLOUT)
BASELINE_PROFILES_OPTIMIZER_INTEGRATION_DICT = make_dict(BASELINE_PROFILES_OPTIMIZER_INTEGRATION)
-ENFORCE_MIN_SDK_FLOOR_ROLLOUT_DICT = make_dict(ENFORCE_MIN_SDK_FLOOR_ROLLOUT)
-ENFORCE_MIN_SDK_FLOOR_FALLBACK_DICT = make_dict(ENFORCE_MIN_SDK_FLOOR_FALLBACK)
+MIN_SDK_FLOORS_DICT = make_min_sdk_dict(MIN_SDK_FLOORS)
ANDROID_APK_TO_BUNDLE_FEATURES_DICT = make_dict(ANDROID_APK_TO_BUNDLE_FEATURES)
ANDROID_LIBRARY_USE_AOSP_AIDL_COMPILER_ALLOWLIST_DICT = make_dict(ANDROID_LIBRARY_USE_AOSP_AIDL_COMPILER_ALLOWLIST)
ANDROID_LOCAL_TEST_JDK_STS_FALLBACK_DICT = make_dict(ANDROID_LOCAL_TEST_JDK_STS_FALLBACK)
@@ -371,6 +379,7 @@ def matches(fqn, dct):
acls = struct(
get_android_archive_duplicate_class_allowlist = _get_android_archive_duplicate_class_allowlist,
get_android_archive_exposed_package_allowlist = _get_android_archive_exposed_package_allowlist,
+ get_min_sdk_floor = _get_min_sdk_floor,
in_aar_import_deps_checker = _in_aar_import_deps_checker,
in_aar_import_explicit_exports_manifest = _in_aar_import_explicit_exports_manifest,
in_aar_import_exports_r_java = _in_aar_import_exports_r_java,
@@ -412,7 +421,6 @@ acls = struct(
in_android_instrumentation_test_prebuilt_test_apk = _in_android_instrumentation_test_prebuilt_test_apk,
in_baseline_profiles_rollout = _in_baseline_profiles_rollout,
in_baseline_profiles_optimizer_integration = _in_baseline_profiles_optimizer_integration,
- in_enforce_min_sdk_floor_rollout = _in_enforce_min_sdk_floor_rollout,
in_android_apk_to_bundle_features = _in_android_apk_to_bundle_features,
in_android_local_test_jdk_sts_rollout = _in_android_local_test_jdk_sts_rollout,
in_shared_library_resource_linking_allowlist = _in_shared_library_resource_linking_allowlist,
diff --git a/rules/acls/enforce_min_sdk_floor_rollout.bzl b/rules/acls/min_sdk_floors.bzl
index 94643eb..4dfe044 100644
--- a/rules/acls/enforce_min_sdk_floor_rollout.bzl
+++ b/rules/acls/min_sdk_floors.bzl
@@ -1,4 +1,4 @@
-# Copyright 2022 The Bazel Authors. All rights reserved.
+# Copyright 2023 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,11 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-"""Rollout list for enabling enforce min SDK floor."""
+"""Mapping of minSdkVersion floors to packages.
-ENFORCE_MIN_SDK_FLOOR_ROLLOUT = [
- "//:__subpackages__",
-]
+Starlark dictionaries maintain insertion order. It is expected that the union of all lists will
+cover the entire depot.
+"""
-ENFORCE_MIN_SDK_FLOOR_FALLBACK = [
-]
+MIN_SDK_FLOORS = {
+ 19: [
+ "//:__subpackages__",
+ ],
+ 14: [
+ "//:__subpackages__",
+ ],
+}
diff --git a/rules/android_application/android_application_rule.bzl b/rules/android_application/android_application_rule.bzl
index a2c9b70..d7c15c2 100644
--- a/rules/android_application/android_application_rule.bzl
+++ b/rules/android_application/android_application_rule.bzl
@@ -261,8 +261,8 @@ def _impl(ctx):
ctx,
out = module,
proto_apk = proto_apk,
- unzip = get_android_toolchain(ctx).unzip_tool.files_to_run,
- zip = get_android_toolchain(ctx).zip_tool.files_to_run,
+ bundletool_module_builder =
+ get_android_toolchain(ctx).bundletool_module_builder.files_to_run,
)
metadata = dict()
diff --git a/rules/android_binary_internal/attrs.bzl b/rules/android_binary_internal/attrs.bzl
index 9a2df04..e09f3e1 100644
--- a/rules/android_binary_internal/attrs.bzl
+++ b/rules/android_binary_internal/attrs.bzl
@@ -14,16 +14,17 @@
"""Attributes."""
+load("//rules:android_neverlink_aspect.bzl", "android_neverlink_aspect")
load(
"//rules:attrs.bzl",
_attrs = "attrs",
)
+load("//rules:dex_desugar_aspect.bzl", "dex_desugar_aspect")
load(
"//rules:native_deps.bzl",
"split_config_aspect",
)
load("//rules:providers.bzl", "StarlarkApkInfo")
-load("//rules:dex_desugar_aspect.bzl", "dex_desugar_aspect")
def make_deps(allow_rules, providers, aspects):
return attr.label_list(
@@ -51,6 +52,7 @@ DEPS_PROVIDERS = [
DEPS_ASPECTS = [
dex_desugar_aspect,
+ android_neverlink_aspect,
]
ATTRS = _attrs.replace(
diff --git a/rules/android_binary_internal/impl.bzl b/rules/android_binary_internal/impl.bzl
index a1e42df..0c156de 100644
--- a/rules/android_binary_internal/impl.bzl
+++ b/rules/android_binary_internal/impl.bzl
@@ -31,7 +31,7 @@ load(
"ProviderInfo",
"processing_pipeline",
)
-load("//rules:proguard.bzl", "proguard", proguard_testing = "testing")
+load("//rules:proguard.bzl", "proguard")
load("//rules:providers.bzl", "StarlarkAndroidDexInfo", "StarlarkApkInfo")
load("//rules:resources.bzl", _resources = "resources")
load(
@@ -53,7 +53,7 @@ def _process_manifest(ctx, **unused_ctxs):
ctx,
manifest = ctx.file.manifest,
manifest_values = ctx.attr.manifest_values,
- floor = _resources.DEPOT_MIN_SDK_FLOOR if (_is_test_binary(ctx) and acls.in_enforce_min_sdk_floor_rollout(str(ctx.label))) else 0,
+ floor = acls.get_min_sdk_floor(str(ctx.label)) if _is_test_binary(ctx) else 0,
enforce_min_sdk_floor_tool = get_android_toolchain(ctx).enforce_min_sdk_floor_tool.files_to_run,
)
@@ -109,7 +109,7 @@ def _validate_manifest(ctx, packaged_resources_ctx, **unused_ctxs):
manifest_validation_ctx = _resources.validate_min_sdk(
ctx,
manifest = packaged_resources_ctx.processed_manifest,
- floor = _resources.DEPOT_MIN_SDK_FLOOR if acls.in_enforce_min_sdk_floor_rollout(str(ctx.label)) else 0,
+ floor = acls.get_min_sdk_floor(str(ctx.label)),
enforce_min_sdk_floor_tool = get_android_toolchain(ctx).enforce_min_sdk_floor_tool.files_to_run,
)
@@ -260,7 +260,7 @@ def _process_dex(ctx, stamp_ctx, packaged_resources_ctx, jvm_ctx, proto_ctx, dep
main_dex_classes = get_android_sdk(ctx).main_dex_classes,
main_dex_list_opts = ctx.attr.main_dex_list_opts,
main_dex_proguard_spec = packaged_resources_ctx.main_dex_proguard_config,
- proguard_specs = list(ctx.attr.main_dex_proguard_specs),
+ proguard_specs = list(ctx.files.main_dex_proguard_specs),
shrinked_android_jar = get_android_sdk(ctx).shrinked_android_jar,
main_dex_list_creator = get_android_sdk(ctx).main_dex_list_creator,
legacy_main_dex_list_generator =
@@ -389,11 +389,16 @@ def _process_dex(ctx, stamp_ctx, packaged_resources_ctx, jvm_ctx, proto_ctx, dep
dex_info = AndroidDexInfo(
deploy_jar = deploy_jar,
+ filtered_deploy_jar = deploy_ctx.filtered_deploy_jar,
final_classes_dex_zip = final_classes_dex_zip,
final_proguard_output_map = final_proguard_output_map,
- java_resource_jar = deploy_jar,
+ java_resource_jar = binary_jar if ctx.fragments.android.get_java_resources_from_optimized_jar else deploy_jar,
)
providers.append(dex_info)
+ providers.append(AndroidPreDexJarInfo(binary_jar))
+
+ if postprocessing_output_map:
+ providers.append(ProguardMappingInfo(postprocessing_output_map))
return ProviderInfo(
name = "dex_ctx",
@@ -405,7 +410,7 @@ def _process_dex(ctx, stamp_ctx, packaged_resources_ctx, jvm_ctx, proto_ctx, dep
)
def _process_deploy_jar(ctx, stamp_ctx, packaged_resources_ctx, jvm_ctx, build_info_ctx, proto_ctx, **_unused_ctxs):
- deploy_jar, desugar_dict = None, {}
+ deploy_jar, filtered_deploy_jar, desugar_dict = None, None, {}
if acls.in_android_binary_starlark_dex_desugar_proguard(str(ctx.label)):
java_toolchain = common.get_java_toolchain(ctx)
@@ -456,7 +461,9 @@ def _process_deploy_jar(ctx, stamp_ctx, packaged_resources_ctx, jvm_ctx, build_i
if _is_instrumentation(ctx):
filtered_deploy_jar = ctx.actions.declare_file(ctx.label.name + "_migrated_filtered.jar")
- filter_jar = ctx.attr.instruments[AndroidPreDexJarInfo].pre_dex_jar
+
+ # TODO(b/303286042): Use AndroidPreDexInfo.pre_dex_jar to be the filter_jar
+ filter_jar = ctx.attr.instruments[ApkInfo].deploy_jar
common.filter_zip_exclude(
ctx,
output = filtered_deploy_jar,
@@ -474,6 +481,7 @@ def _process_deploy_jar(ctx, stamp_ctx, packaged_resources_ctx, jvm_ctx, build_i
value = struct(
deploy_jar = deploy_jar,
desugar_dict = desugar_dict,
+ filtered_deploy_jar = filtered_deploy_jar,
providers = [],
),
)
@@ -639,7 +647,7 @@ def _process_optimize(ctx, deploy_ctx, packaged_resources_ctx, bp_ctx, **_unused
)
# Validate attributes and lockdown lists
- if ctx.file.proguard_apply_mapping and not acls.in_allow_proguard_apply_mapping(ctx.label):
+ if ctx.file.proguard_apply_mapping and not acls.in_allow_proguard_apply_mapping(str(ctx.label)):
fail("proguard_apply_mapping is not supported")
if ctx.file.proguard_apply_mapping and not ctx.files.proguard_specs:
fail("proguard_apply_mapping can only be used when proguard_specs is set")
@@ -650,7 +658,6 @@ def _process_optimize(ctx, deploy_ctx, packaged_resources_ctx, bp_ctx, **_unused
proguard_specs_for_manifest = [packaged_resources_ctx.resource_minsdk_proguard_config] if packaged_resources_ctx.resource_minsdk_proguard_config else [],
)
has_proguard_specs = bool(proguard_specs)
- proguard_output = struct()
is_resource_shrinking_enabled = _resources.is_resource_shrinking_enabled(
ctx.attr.shrink_resources,
@@ -684,8 +691,11 @@ def _process_optimize(ctx, deploy_ctx, packaged_resources_ctx, bp_ctx, **_unused
proguard_seeds = ctx.actions.declare_file(ctx.label.name + "_migrated_proguard.seeds")
proguard_usage = ctx.actions.declare_file(ctx.label.name + "_migrated_proguard.usage")
- startup_profile = bp_ctx.baseline_profile_output.startup_profile if bp_ctx.baseline_profile_output else None
- baseline_profile = bp_ctx.baseline_profile_output.baseline_profile if bp_ctx.baseline_profile_output else None
+ startup_profile = None
+ baseline_profile = None
+ if acls.in_baseline_profiles_optimizer_integration(str(ctx.label)) and bp_ctx.baseline_profile_output:
+ startup_profile = bp_ctx.baseline_profile_output.startup_profile
+ baseline_profile = bp_ctx.baseline_profile_output.baseline_profile
proguard_output = proguard.apply_proguard(
ctx,
@@ -702,20 +712,6 @@ def _process_optimize(ctx, deploy_ctx, packaged_resources_ctx, bp_ctx, **_unused
proguard_tool = get_android_sdk(ctx).proguard,
)
- providers = []
- if proguard_output:
- providers.append(proguard_testing.ProguardOutputInfo(
- input_jar = deploy_ctx.deploy_jar,
- output_jar = proguard_output.output_jar,
- mapping = proguard_output.mapping,
- seeds = proguard_output.seeds,
- usage = proguard_output.usage,
- library_jar = proguard_output.library_jar,
- config = proguard_output.config,
- baseline_profile_rewritten = proguard_output.baseline_profile_rewritten,
- startup_profile_rewritten = proguard_output.startup_profile_rewritten,
- ))
-
use_resource_shrinking = is_resource_shrinking_enabled and has_proguard_specs
shrunk_resource_output = None
if use_resource_shrinking:
@@ -730,7 +726,6 @@ def _process_optimize(ctx, deploy_ctx, packaged_resources_ctx, bp_ctx, **_unused
busybox = get_android_toolchain(ctx).android_resources_busybox.files_to_run,
host_javabase = common.get_host_javabase(ctx),
)
- providers.append(shrunk_resource_output)
optimized_resource_output = _resources.optimize(
ctx,
@@ -741,7 +736,26 @@ def _process_optimize(ctx, deploy_ctx, packaged_resources_ctx, bp_ctx, **_unused
busybox = get_android_toolchain(ctx).android_resources_busybox.files_to_run,
host_javabase = common.get_host_javabase(ctx),
)
- providers.append(optimized_resource_output)
+
+ providers = []
+ providers.append(
+ AndroidOptimizationInfo(
+ optimized_jar = proguard_output.output_jar,
+ mapping = proguard_output.mapping,
+ seeds = proguard_output.seeds,
+ library_jar = proguard_output.library_jar,
+ config = proguard_output.config,
+ proto_mapping = proguard_output.proto_mapping,
+ rewritten_startup_profile = proguard_output.startup_profile_rewritten,
+ rewriten_merged_baseline_profile = proguard_output.baseline_profile_rewritten,
+ optimized_resource_apk = optimized_resource_output.resources_apk,
+ shrunk_resource_apk = shrunk_resource_output.resources_apk if shrunk_resource_output else None,
+ shrunk_resource_zip = shrunk_resource_output.resources_zip if shrunk_resource_output else None,
+ resource_shrinker_log = shrunk_resource_output.shrinker_log if shrunk_resource_output else None,
+ resource_optimization_config = shrunk_resource_output.optimization_config if shrunk_resource_output else None,
+ resource_path_shortening_map = optimized_resource_output.path_shortening_map,
+ ),
+ )
return ProviderInfo(
name = "optimize_ctx",
diff --git a/rules/android_binary_internal/r8.bzl b/rules/android_binary_internal/r8.bzl
index 90c91c3..0ace549 100644
--- a/rules/android_binary_internal/r8.bzl
+++ b/rules/android_binary_internal/r8.bzl
@@ -92,6 +92,7 @@ def process_r8(ctx, jvm_ctx, packaged_resources_ctx, build_info_ctx, **_unused_c
inputs = [android_jar, deploy_jar] + proguard_specs,
outputs = [dexes_zip],
mnemonic = "AndroidR8",
+ jvm_flags = ["-Xmx8G"],
progress_message = "R8 Optimizing, Desugaring, and Dexing %{label}",
)
diff --git a/rules/android_library/impl.bzl b/rules/android_library/impl.bzl
index 5fd5af5..6ccc5a5 100644
--- a/rules/android_library/impl.bzl
+++ b/rules/android_library/impl.bzl
@@ -133,7 +133,7 @@ def _process_manifest(ctx, **unused_ctxs):
manifest_ctx = _resources.bump_min_sdk(
ctx,
manifest = ctx.file.manifest,
- floor = _resources.DEPOT_MIN_SDK_FLOOR if acls.in_enforce_min_sdk_floor_rollout(str(ctx.label)) else 0,
+ floor = acls.get_min_sdk_floor(str(ctx.label)),
enforce_min_sdk_floor_tool = get_android_toolchain(ctx).enforce_min_sdk_floor_tool.files_to_run,
)
diff --git a/rules/android_library/rule.bzl b/rules/android_library/rule.bzl
index e36bdd3..cd7af67 100644
--- a/rules/android_library/rule.bzl
+++ b/rules/android_library/rule.bzl
@@ -140,7 +140,8 @@ def make_rule(
attrs = _ATTRS,
implementation = _impl,
outputs = _outputs,
- additional_toolchains = []):
+ additional_toolchains = [],
+ additional_providers = []):
"""Makes the rule.
Args:
@@ -148,6 +149,7 @@ def make_rule(
implementation: A function. The rule's implementation method.
outputs: A dict, function, or None. The rule's outputs.
additional_toolchains: A list. Additional toolchains passed to pass to rule(toolchains).
+ additional_providers: A list. Additional providers passed to pass to rule(providers).
Returns:
A rule.
@@ -167,7 +169,7 @@ def make_rule(
AndroidLibraryResourceClassJarProvider,
AndroidNativeLibsInfo,
JavaInfo,
- ],
+ ] + additional_providers,
outputs = outputs,
toolchains = [
"//toolchains/android:toolchain_type",
diff --git a/rules/android_local_test/impl.bzl b/rules/android_local_test/impl.bzl
index 1606e18..3a6221f 100644
--- a/rules/android_local_test/impl.bzl
+++ b/rules/android_local_test/impl.bzl
@@ -61,7 +61,7 @@ def _process_manifest(ctx, java_package, **_unused_sub_ctxs):
manifest_values = resources.process_manifest_values(
ctx,
ctx.attr.manifest_values,
- resources.DEPOT_MIN_SDK_FLOOR,
+ acls.get_min_sdk_floor(str(ctx.label)),
)
if ctx.file.manifest == None:
# No manifest provided, generate one
@@ -70,7 +70,7 @@ def _process_manifest(ctx, java_package, **_unused_sub_ctxs):
ctx,
out_manifest = manifest,
java_package = java_package,
- min_sdk_version = manifest_values.get("minSdkVersion", 16), # minsdk supported by robolectric framework
+ min_sdk_version = int(manifest_values.get("minSdkVersion", 16)), # minsdk supported by robolectric framework
)
manifest_ctx = struct(processed_manifest = manifest, processed_manifest_values = manifest_values)
else:
@@ -78,7 +78,7 @@ def _process_manifest(ctx, java_package, **_unused_sub_ctxs):
ctx,
manifest = ctx.file.manifest,
manifest_values = ctx.attr.manifest_values,
- floor = resources.DEPOT_MIN_SDK_FLOOR if acls.in_enforce_min_sdk_floor_rollout(str(ctx.label)) else 0,
+ floor = acls.get_min_sdk_floor(str(ctx.label)),
enforce_min_sdk_floor_tool = get_android_toolchain(ctx).enforce_min_sdk_floor_tool.files_to_run,
)
diff --git a/rules/android_neverlink_aspect.bzl b/rules/android_neverlink_aspect.bzl
index 1dab304..672bd3a 100644
--- a/rules/android_neverlink_aspect.bzl
+++ b/rules/android_neverlink_aspect.bzl
@@ -18,6 +18,7 @@ Used for determining the -libraryjars argument for Proguard. The compile-time cl
unsufficient here as those are ijars.
"""
+load("//rules:acls.bzl", "acls")
load(
"//rules:utils.bzl",
"utils",
@@ -33,6 +34,9 @@ StarlarkAndroidNeverlinkInfo = provider(
_ATTRS = ["deps", "exports", "runtime_deps", "binary_under_test", "$instrumentation_test_runner"]
def _android_neverlink_aspect_impl(target, ctx):
+ if not acls.in_android_binary_starlark_dex_desugar_proguard(str(ctx.label)):
+ return []
+
# Only run on Android targets
if "android" not in getattr(ctx.rule.attr, "constraints", "") and not ctx.rule.kind.startswith("android_"):
return []
diff --git a/rules/android_sandboxed_sdk/android_binary_with_sandboxed_sdks_macro.bzl b/rules/android_sandboxed_sdk/android_binary_with_sandboxed_sdks_macro.bzl
index 95b8b80..1499e98 100644
--- a/rules/android_sandboxed_sdk/android_binary_with_sandboxed_sdks_macro.bzl
+++ b/rules/android_sandboxed_sdk/android_binary_with_sandboxed_sdks_macro.bzl
@@ -14,19 +14,20 @@
"""Bazel rule for defining an Android binary that depends on sandboxed SDKs."""
-load(":providers.bzl", "AndroidSandboxedSdkBundleInfo")
load("//rules:acls.bzl", "acls")
load("//rules:bundletool.bzl", _bundletool = "bundletool")
load("//rules:common.bzl", _common = "common")
-load(
- "//rules:utils.bzl",
- _get_android_toolchain = "get_android_toolchain",
-)
load("//rules:java.bzl", _java = "java")
load(
"//rules:sandboxed_sdk_toolbox.bzl",
_sandboxed_sdk_toolbox = "sandboxed_sdk_toolbox",
)
+load(
+ "//rules:utils.bzl",
+ "utils",
+ _get_android_toolchain = "get_android_toolchain",
+)
+load(":providers.bzl", "AndroidArchivedSandboxedSdkInfo", "AndroidSandboxedSdkBundleInfo")
def _gen_sdk_dependencies_manifest_impl(ctx):
manifest = ctx.actions.declare_file(ctx.label.name + "_sdk_dep_manifest.xml")
@@ -34,12 +35,17 @@ def _gen_sdk_dependencies_manifest_impl(ctx):
bundle[AndroidSandboxedSdkBundleInfo].sdk_info.sdk_module_config
for bundle in ctx.attr.sdk_bundles
]
+ sdk_archives = [
+ archive[AndroidArchivedSandboxedSdkInfo].asar
+ for archive in ctx.attr.sdk_archives
+ ]
_sandboxed_sdk_toolbox.generate_sdk_dependencies_manifest(
ctx,
output = manifest,
manifest_package = ctx.attr.package,
sdk_module_configs = module_configs,
+ sdk_archives = sdk_archives,
debug_key = ctx.file.debug_key,
sandboxed_sdk_toolbox = _get_android_toolchain(ctx).sandboxed_sdk_toolbox.files_to_run,
host_javabase = _common.get_host_javabase(ctx),
@@ -59,6 +65,11 @@ _gen_sdk_dependencies_manifest = rule(
[AndroidSandboxedSdkBundleInfo],
],
),
+ sdk_archives = attr.label_list(
+ providers = [
+ [AndroidArchivedSandboxedSdkInfo],
+ ],
+ ),
debug_key = attr.label(
allow_single_file = True,
default = Label("//tools/android:debug_keystore"),
@@ -78,8 +89,34 @@ _gen_sdk_dependencies_manifest = rule(
def _android_binary_with_sandboxed_sdks_impl(ctx):
sdk_apks = []
+ for idx, sdk_archive in enumerate(ctx.attr.sdk_archives):
+ # Bundletool is rejecting ASARs when creating APKs, but since the formats are similar enough
+ # for this command we can just rename the file.
+ # TODO b/294970460) -- Remove this extra copy once Bundletool is updated with ASAR support
+ # in build_sdk_apks. Their work is being tracked in b/228176834.
+ renamed_sdk_archive = ctx.actions.declare_file("%s/renamed_sdk_archive/%s.asb" % (
+ ctx.label.name,
+ idx,
+ ))
+ utils.copy_file(ctx, sdk_archive[AndroidArchivedSandboxedSdkInfo].asar, renamed_sdk_archive)
+
+ apk_out = ctx.actions.declare_file("%s/sdk_archive_dep_apks/%s.apk" % (
+ ctx.label.name,
+ idx,
+ ))
+ _bundletool.build_sdk_apks(
+ ctx,
+ out = apk_out,
+ aapt2 = _get_android_toolchain(ctx).aapt2.files_to_run,
+ sdk_bundle = renamed_sdk_archive,
+ debug_key = ctx.file.debug_key,
+ bundletool = _get_android_toolchain(ctx).bundletool.files_to_run,
+ host_javabase = _common.get_host_javabase(ctx),
+ )
+ sdk_apks.append(apk_out)
+
for idx, sdk_bundle_target in enumerate(ctx.attr.sdk_bundles):
- apk_out = ctx.actions.declare_file("%s/sdk_dep_apks/%s.apk" % (
+ apk_out = ctx.actions.declare_file("%s/sdk_bundle_dep_apks/%s.apk" % (
ctx.label.name,
idx,
))
@@ -137,6 +174,11 @@ _android_binary_with_sandboxed_sdks = rule(
[AndroidSandboxedSdkBundleInfo],
],
),
+ sdk_archives = attr.label_list(
+ providers = [
+ [AndroidArchivedSandboxedSdkInfo],
+ ],
+ ),
_install_script_template = attr.label(
allow_single_file = True,
default = ":install_script.sh_template",
@@ -150,6 +192,7 @@ _android_binary_with_sandboxed_sdks = rule(
implementation = _android_binary_with_sandboxed_sdks_impl,
toolchains = [
"//toolchains/android:toolchain_type",
+ "@bazel_tools//tools/jdk:toolchain_type",
],
)
@@ -171,7 +214,8 @@ def android_binary_with_sandboxed_sdks_macro(
fail("%s is not allowed to use the android_binary_with_sandboxed_sdks macro." %
fully_qualified_name)
- sdk_bundles = attrs.pop("sdk_bundles", None)
+ sdk_bundles = attrs.pop("sdk_bundles", [])
+ sdk_archives = attrs.pop("sdk_archives", [])
debug_keystore = getattr(attrs, "debug_keystore", None)
bin_package = _java.resolve_package_from_label(
@@ -185,6 +229,10 @@ def android_binary_with_sandboxed_sdks_macro(
name = sdk_dependencies_manifest_name,
package = "%s.internalsdkdependencies" % bin_package,
sdk_bundles = sdk_bundles,
+ sdk_archives = sdk_archives,
+ testonly = attrs.get("testonly", False),
+ tags = attrs.get("tags", []),
+ visibility = attrs.get("visibility", None),
)
# Use the manifest in a normal android_library. This will later be added as a dependency to the
@@ -194,6 +242,10 @@ def android_binary_with_sandboxed_sdks_macro(
name = sdk_dependencies_lib_name,
exports_manifest = 1,
manifest = ":%s" % sdk_dependencies_manifest_name,
+ testonly = attrs.get("testonly", False),
+ tags = attrs.get("tags", []),
+ transitive_configs = attrs.get("transitive_configs", []),
+ visibility = attrs.get("visibility", None),
)
deps = attrs.pop("deps", [])
deps.append(":%s" % sdk_dependencies_lib_name)
@@ -210,6 +262,10 @@ def android_binary_with_sandboxed_sdks_macro(
_android_binary_with_sandboxed_sdks(
name = name,
sdk_bundles = sdk_bundles,
+ sdk_archives = sdk_archives,
debug_key = debug_keystore,
internal_android_binary = bin_label,
+ testonly = attrs.get("testonly", False),
+ tags = attrs.get("tags", []),
+ visibility = attrs.get("visibility", None),
)
diff --git a/rules/android_sdk_repository/helper.bzl b/rules/android_sdk_repository/helper.bzl
index 43f715f..3a2eba4 100644
--- a/rules/android_sdk_repository/helper.bzl
+++ b/rules/android_sdk_repository/helper.bzl
@@ -235,6 +235,8 @@ def create_android_sdk_rules(
],
)
+ create_dummy_sdk_toolchain()
+
native.alias(
name = "org_apache_http_legacy",
actual = ":org_apache_http_legacy-%d" % default_api_level,
@@ -504,4 +506,45 @@ def create_system_images_filegroups(system_image_dirs):
native.filegroup(
name = "%s_qemu2_extra" % name,
srcs = [],
- )
+ ) # buildifier: disable=unnamed-macro
+
+# This is a dummy sdk toolchain that matches any platform. It will
+# fail if actually resolved to and used.
+# buildifier: disable=unnamed-macro
+def create_dummy_sdk_toolchain():
+ "Create a dummy SDK for fallback builds"
+
+ native.toolchain(
+ name = "sdk-dummy-toolchain",
+ toolchain = ":sdk-dummy",
+ toolchain_type = "@bazel_tools//tools/android:sdk_toolchain_type",
+ )
+
+ native.filegroup(name = "jar-filegroup", srcs = ["dummy.jar"])
+
+ native.genrule(
+ name = "genrule",
+ srcs = [],
+ outs = ["empty.sh"],
+ cmd = "echo '' >> \"$@\"",
+ executable = 1,
+ )
+
+ native.sh_binary(name = "empty-binary", srcs = [":genrule"])
+
+ native.android_sdk(
+ name = "sdk-dummy",
+ aapt = ":empty-binary",
+ adb = ":empty-binary",
+ aidl = ":empty-binary",
+ android_jar = ":jar-filegroup",
+ apksigner = ":empty-binary",
+ dx = ":empty-binary",
+ framework_aidl = "dummy.jar",
+ main_dex_classes = "dummy.jar",
+ main_dex_list_creator = ":empty-binary",
+ proguard = ":empty-binary",
+ shrinked_android_jar = "dummy.jar",
+ tags = ["__ANDROID_RULES_MIGRATION__"],
+ zipalign = ":empty-binary",
+ )
diff --git a/rules/attrs.bzl b/rules/attrs.bzl
index 6a03d2d..a72fd4f 100644
--- a/rules/attrs.bzl
+++ b/rules/attrs.bzl
@@ -267,6 +267,12 @@ ANDROID_SDK_ATTRS = dict(
mandatory = True,
),
build_tools_version = attr.string(),
+ dexdump = attr.label(
+ allow_files = True,
+ cfg = "exec",
+ executable = True,
+ mandatory = False,
+ ),
dx = attr.label(
allow_files = True,
cfg = "exec",
diff --git a/rules/bundletool.bzl b/rules/bundletool.bzl
index b0651ec..a933211 100644
--- a/rules/bundletool.bzl
+++ b/rules/bundletool.bzl
@@ -322,71 +322,17 @@ def _proto_apk_to_module(
ctx,
out = None,
proto_apk = None,
- zip = None,
- unzip = None):
- # TODO(timpeut): migrate this to Bundletool module builder.
- ctx.actions.run_shell(
- command = """
-set -e
-
-IN_DIR=$(mktemp -d)
-OUT_DIR=$(mktemp -d)
-CUR_PWD=$(pwd)
-UNZIP=%s
-ZIP=%s
-INPUT=%s
-OUTPUT=%s
-
-"${UNZIP}" -qq "${INPUT}" -d "${IN_DIR}"
-cd "${IN_DIR}"
-
-if [ -f resources.pb ]; then
- mv resources.pb "${OUT_DIR}/"
-fi
-
-if [ -f AndroidManifest.xml ]; then
- mkdir "${OUT_DIR}/manifest"
- mv AndroidManifest.xml "${OUT_DIR}/manifest/"
-fi
-
-NUM_DEX=`ls -1 *.dex 2>/dev/null | wc -l`
-if [ $NUM_DEX != 0 ]; then
- mkdir "${OUT_DIR}/dex"
- mv *.dex "${OUT_DIR}/dex/"
-fi
-
-if [ -d res ]; then
- mv res "${OUT_DIR}/res"
-fi
-
-if [ -d assets ]; then
- mv assets "${OUT_DIR}/"
-fi
-
-if [ -d lib ]; then
- mv lib "${OUT_DIR}/"
-fi
-
-UNKNOWN=`ls -1 * 2>/dev/null | wc -l`
-if [ $UNKNOWN != 0 ]; then
- mkdir "${OUT_DIR}/root"
- mv * "${OUT_DIR}/root/"
-fi
-
-cd "${OUT_DIR}"
-"${CUR_PWD}/${ZIP}" "${CUR_PWD}/${OUTPUT}" -Drq0 .
-""" % (
- unzip.executable.path,
- zip.executable.path,
- proto_apk.path,
- out.path,
- ),
- tools = [zip, unzip],
- arguments = [],
+ bundletool_module_builder = None):
+ args = ctx.actions.args()
+ args.add("--internal_apk_path", proto_apk)
+ args.add("--output_module_path", out)
+ ctx.actions.run(
inputs = [proto_apk],
outputs = [out],
- mnemonic = "Rebundle",
- progress_message = "Rebundle to %s" % out.short_path,
+ executable = bundletool_module_builder,
+ arguments = [args],
+ mnemonic = "BuildAppModule",
+ progress_message = "Building AAB zip module %s" % out.short_path,
toolchain = ANDROID_TOOLCHAIN_TYPE,
)
diff --git a/rules/busybox.bzl b/rules/busybox.bzl
index ce36d52..bcbb880 100644
--- a/rules/busybox.bzl
+++ b/rules/busybox.bzl
@@ -1150,8 +1150,8 @@ def _optimize(
host_javabase: Target. The host javabase.
"""
- output_files = []
- input_files = []
+ output_files = [out_apk]
+ input_files = [in_apk]
args = ctx.actions.args()
args.use_param_file("@%s")
@@ -1168,7 +1168,6 @@ def _optimize(
args.add("--resources-config-path", resource_optimization_config)
input_files.append(resource_optimization_config)
args.add("-o", out_apk)
- output_files.append(out_apk)
args.add(in_apk)
_java.run(
diff --git a/rules/dex.bzl b/rules/dex.bzl
index 4ab7704..a3e2620 100644
--- a/rules/dex.bzl
+++ b/rules/dex.bzl
@@ -50,12 +50,7 @@ def _process_incremental_dexing(
incremental_dexopts = _filter_dexopts(dexopts, ctx.fragments.android.get_dexopts_supported_in_incremental_dexing)
inclusion_filter_jar = proguarded_jar
if not proguarded_jar:
- dex_archives_list = info.dex_archives_dict.get("".join(incremental_dexopts), depset()).to_list()
- dex_archives = _to_dexed_classpath(
- dex_archives_dict = {d.jar: d.dex for d in dex_archives_list},
- classpath = _filter(java_info.transitive_runtime_jars.to_list(), excludes = _get_library_r_jars(deps)),
- runtime_jars = runtime_jars,
- )
+ dex_archives = []
for jar in runtime_jars:
dex_archive = _get_dx_artifact(ctx, jar.basename + ".dex.zip")
_dex(
@@ -68,6 +63,11 @@ def _process_incremental_dexing(
toolchain_type = toolchain_type,
)
dex_archives.append(dex_archive)
+ dex_archives += _to_dexed_classpath(
+ dex_archives_dict = {d.jar: d.dex for d in info.dex_archives_dict.get("".join(incremental_dexopts), depset()).to_list()},
+ classpath = _filter(java_info.transitive_runtime_jars.to_list(), excludes = _get_library_r_jars(deps)),
+ runtime_jars = runtime_jars,
+ )
else:
java_resource_jar = ctx.actions.declare_file(ctx.label.name + "_files/java_resources.jar")
if ctx.fragments.android.incremental_dexing_shards_after_proguard > 1:
@@ -332,7 +332,7 @@ def _shard_dexes(
outputs = [output],
inputs = inputs,
arguments = [args],
- mnemonic = "ShardsForMultiDex",
+ mnemonic = "ShardForMultidex",
progress_message = "Assembling dex files for " + ctx.label.name,
use_default_shell_env = True,
toolchain = toolchain_type,
@@ -396,6 +396,8 @@ def _dex(
dex_exec: File. The executable dex builder file.
"""
args = ctx.actions.args()
+ args.use_param_file("@%s", use_always = True) # Required for workers.
+ args.set_param_file_format("multiline")
args.add("--input_jar", input)
args.add("--output_zip", output)
diff --git a/rules/dex_desugar_aspect.bzl b/rules/dex_desugar_aspect.bzl
index 9d692d3..066ad1a 100644
--- a/rules/dex_desugar_aspect.bzl
+++ b/rules/dex_desugar_aspect.bzl
@@ -14,7 +14,7 @@
"""Aspect that transitively build .dex archives and desugar jars."""
-load(":utils.bzl", _utils = "utils")
+load(":utils.bzl", _get_android_sdk = "get_android_sdk", _utils = "utils")
load(":dex.bzl", _dex = "dex")
load(":desugar.bzl", _desugar = "desugar")
load(":providers.bzl", "StarlarkAndroidDexInfo")
@@ -193,8 +193,10 @@ def _get_boot_classpath(target, ctx):
compilation_info = target[JavaInfo].compilation_info
if compilation_info and compilation_info.boot_classpath:
return compilation_info.boot_classpath
- if ctx.attr._android_sdk and ctx.attr._android_sdk[AndroidSdkInfo].android_jar:
- return [ctx.attr._android_sdk[AndroidSdkInfo].android_jar]
+
+ android_jar = _get_android_sdk(ctx).android_jar
+ if android_jar:
+ return [android_jar]
# This shouldn't ever be reached, but if it is, we should be clear about the error.
fail("No compilation info or android jar!")
@@ -249,5 +251,6 @@ dex_desugar_aspect = aspect(
_attrs.ANDROID_SDK,
),
fragments = ["android"],
+ toolchains = ["//toolchains/android_sdk:toolchain_type"],
required_aspect_providers = [[JavaInfo]],
)
diff --git a/rules/instrumented_app_info_aspect.bzl b/rules/instrumented_app_info_aspect.bzl
new file mode 100644
index 0000000..0d457c6
--- /dev/null
+++ b/rules/instrumented_app_info_aspect.bzl
@@ -0,0 +1,26 @@
+# Copyright 2021 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+"""This aspect is used to collect providers from an instrumented android_binary."""
+
+load("//rules:providers.bzl", "InstrumentedAppInfo")
+
+def _impl(unused_target, ctx):
+ if hasattr(ctx.rule.attr, "instruments") and ctx.rule.attr.instruments and AndroidIdeInfo in ctx.rule.attr.instruments:
+ return [InstrumentedAppInfo(android_ide_info = ctx.rule.attr.instruments[AndroidIdeInfo])]
+ return []
+
+instrumented_app_info_aspect = aspect(
+ implementation = _impl,
+)
diff --git a/rules/native_deps.bzl b/rules/native_deps.bzl
index d503389..1500c47 100644
--- a/rules/native_deps.bzl
+++ b/rules/native_deps.bzl
@@ -179,7 +179,7 @@ def _filter_unique_shared_libs(linked_libs, cc_info):
"Each library in the transitive closure must have a " +
"unique basename to avoid name collisions when packaged into " +
"an apk, but two libraries have the basename '" + basename +
- "': " + artifact + " and " + old_artifact + (
+ "': " + str(artifact) + " and " + str(old_artifact) + (
" (the library already seen by this target)" if old_artifact in linked_libs else ""
),
)
@@ -237,8 +237,16 @@ def _is_shared_library(lib_artifact):
return True
return False
-def _get_build_info(ctx):
- return cc_common.get_build_info(ctx)
+def _is_stamping_enabled(ctx):
+ if ctx.configuration.is_tool_configuration():
+ return 0
+ return getattr(ctx.attr, "stamp", 0)
+
+def _get_build_info(ctx, cc_toolchain):
+ if _is_stamping_enabled(ctx):
+ return cc_toolchain.build_info_files().non_redacted_build_info_files.to_list()
+ else:
+ return cc_toolchain.build_info_files().redacted_build_info_files.to_list()
def _get_shared_native_deps_path(
linker_inputs,
@@ -294,14 +302,19 @@ def _link_native_deps_if_present(ctx, cc_info, cc_toolchain, build_config, actua
build_config.bin_dir,
)
- link_opts = cc_info.linking_context.user_link_flags
+ linker_inputs = cc_info.linking_context.linker_inputs.to_list()
+
+ link_opts = []
+ for linker_input in linker_inputs:
+ for flag in linker_input.user_link_flags:
+ link_opts.append(flag)
linkstamps = []
- for input in cc_info.linking_context.linker_inputs.to_list():
- linkstamps.extend(input.linkstamps)
+ for linker_input in linker_inputs:
+ linkstamps.extend(linker_input.linkstamps)
linkstamps_dict = {linkstamp: None for linkstamp in linkstamps}
- build_info_artifacts = _get_build_info(ctx) if linkstamps_dict else []
+ build_info_artifacts = _get_build_info(ctx, cc_toolchain) if linkstamps_dict else []
requested_features = ["static_linking_mode", "native_deps_link"]
requested_features.extend(ctx.features)
if not "legacy_whole_archive" in ctx.disabled_features:
diff --git a/rules/proguard.bzl b/rules/proguard.bzl
index d5caabb..9599658 100644
--- a/rules/proguard.bzl
+++ b/rules/proguard.bzl
@@ -30,23 +30,6 @@ _ProguardSpecContextInfo = provider(
),
)
-_ProguardOutputInfo = provider(
- doc = "Temporary provider to hold all proguard outputs. Will be replaced by a native " +
- "provider. Useful for testing.",
- fields = dict(
- input_jar = "The input program jar, unoptimized",
- output_jar = "The optimized output jar",
- mapping = "Output proguard map",
- proto_mapping = "Output proto mapping",
- seeds = "Output seeds",
- usage = "Output usage",
- library_jar = "Merged library jar",
- config = "Output config",
- baseline_profile_rewritten = "Optimized baseline profile",
- startup_profile_rewritten = "Optimized startup profile",
- ),
-)
-
def _validate_proguard_spec(
ctx,
out_validated_proguard_spec,
@@ -369,20 +352,32 @@ def _apply_proguard(
proguard_tool: FilesToRun. The proguard executable.
Returns:
- A struct of proguard outputs, corresponding to the fields in ProguardOutputInfo.
+ A struct of proguard outputs.
"""
if not proguard_specs:
+ outputs = _get_proguard_output(
+ ctx,
+ proguard_output_jar = proguard_output_jar,
+ proguard_seeds = None,
+ proguard_usage = None,
+ proguard_output_map = proguard_output_map,
+ combined_library_jar = None,
+ startup_profile_rewritten = None,
+ baseline_profile_rewritten = None,
+ )
+
# Fail at execution time if these artifacts are requested, to avoid issue where outputs are
# declared without having any proguard specs. This can happen if specs is a select() that
# resolves to an empty list.
_fail_action(
ctx,
- proguard_output_jar,
- proguard_output_map,
+ outputs.output_jar,
+ outputs.mapping,
+ outputs.config,
proguard_seeds,
proguard_usage,
)
- return None
+ return outputs
library_jar_list = [get_android_sdk(ctx).android_jar]
if ctx.fragments.android.desugar_java8:
@@ -416,11 +411,19 @@ def _get_proguard_output(
startup_profile_rewritten,
baseline_profile_rewritten):
"""Helper method to get a struct of all proguard outputs."""
+
+ # Proto Output Map is currently empty from ProGuard.
+ proguard_output_proto_map = None
+ if proguard_output_map:
+ proguard_output_proto_map = _get_proguard_temp_artifact(ctx, "_proguard.pbmap")
+ ctx.actions.write(proguard_output_proto_map, content = "")
+
config_output = _get_proguard_temp_artifact(ctx, "_proguard.config")
return struct(
output_jar = proguard_output_jar,
mapping = proguard_output_map,
+ proto_mapping = proguard_output_proto_map,
seeds = proguard_seeds,
usage = proguard_usage,
library_jar = combined_library_jar,
@@ -575,7 +578,7 @@ def _create_optimization_actions(
proguard_specs,
proguard_mapping,
i,
- "_ACTION_%s_OF_%s_" % (j, bytecode_optimization_pass_actions),
+ "_ACTION_%s_OF_%s" % (j, bytecode_optimization_pass_actions),
mnemonic,
last_stage_output,
optimizer_target,
@@ -678,5 +681,4 @@ testing = struct(
collect_transitive_proguard_specs = _collect_transitive_proguard_specs,
optimization_action = _optimization_action,
ProguardSpecContextInfo = _ProguardSpecContextInfo,
- ProguardOutputInfo = _ProguardOutputInfo,
)
diff --git a/rules/resources.bzl b/rules/resources.bzl
index 3f745b9..2ceecc0 100644
--- a/rules/resources.bzl
+++ b/rules/resources.bzl
@@ -32,9 +32,6 @@ load(
_log = "log",
)
-# Depot-wide min SDK floor
-_DEPOT_MIN_SDK_FLOOR = 14
-
_RESOURCE_FOLDER_TYPES = [
"anim",
"animator",
@@ -195,12 +192,12 @@ def _generate_dummy_manifest(
ctx,
out_manifest = None,
java_package = None,
- min_sdk_version = _DEPOT_MIN_SDK_FLOOR):
+ min_sdk_version = 0):
content = """<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="%s">""" % (java_package or "com.default")
- min_sdk_version = max(min_sdk_version, _DEPOT_MIN_SDK_FLOOR)
+ min_sdk_version = max(min_sdk_version, acls.get_min_sdk_floor(str(ctx.label)))
content = content + """
<uses-sdk android:minSdkVersion="%s" />""" % min_sdk_version
@@ -1080,7 +1077,7 @@ def _validate_resources(resource_files = None):
if res_type not in _RESOURCE_FOLDER_TYPES:
fail(_INCORRECT_RESOURCE_LAYOUT_ERROR % resource_file)
-def _process_manifest_values(ctx, manifest_values, min_sdk_floor = _DEPOT_MIN_SDK_FLOOR):
+def _process_manifest_values(ctx, manifest_values, min_sdk_floor):
expanded_manifest_values = utils.expand_make_vars(ctx, manifest_values)
if _MIN_SDK_VERSION in expanded_manifest_values and min_sdk_floor > 0:
expanded_manifest_values[_MIN_SDK_VERSION] = str(
@@ -1092,7 +1089,7 @@ def _bump_min_sdk(
ctx,
manifest = None,
manifest_values = None,
- floor = _DEPOT_MIN_SDK_FLOOR,
+ floor = None,
enforce_min_sdk_floor_tool = None):
"""Bumps the min SDK attribute of AndroidManifest to the floor.
@@ -1109,6 +1106,9 @@ def _bump_min_sdk(
"""
manifest_ctx = {}
+ if floor == None:
+ fail("Missing required `floor` in bump_min_sdk")
+
if manifest_values != None:
manifest_ctx[_PROCESSED_MANIFEST_VALUES] = _process_manifest_values(
ctx,
@@ -1453,7 +1453,7 @@ def _process_starlark(
ctx,
out_manifest = generated_manifest,
java_package = java_package if java_package else ctx.label.package.replace("/", "."),
- min_sdk_version = _DEPOT_MIN_SDK_FLOOR,
+ min_sdk_version = acls.get_min_sdk_floor(str(ctx.label)),
)
r_txt = ctx.actions.declare_file(
"_migrated/" + ctx.label.name + "_symbols/R.txt",
@@ -2101,9 +2101,6 @@ resources = struct(
validate_min_sdk = _validate_min_sdk,
shrink = _shrink,
optimize = _optimize,
-
- # Exposed for android_library, aar_import, and android_binary
- DEPOT_MIN_SDK_FLOOR = _DEPOT_MIN_SDK_FLOOR,
)
testing = struct(
diff --git a/rules/sandboxed_sdk_toolbox.bzl b/rules/sandboxed_sdk_toolbox.bzl
index 1c1a5dd..933212d 100644
--- a/rules/sandboxed_sdk_toolbox.bzl
+++ b/rules/sandboxed_sdk_toolbox.bzl
@@ -128,6 +128,7 @@ def _generate_sdk_dependencies_manifest(
output = None,
manifest_package = None,
sdk_module_configs = None,
+ sdk_archives = None,
debug_key = None,
sandboxed_sdk_toolbox = None,
host_javabase = None):
@@ -141,14 +142,21 @@ def _generate_sdk_dependencies_manifest(
output: File where the final manifest will be written.
manifest_package: The package used in the manifest.
sdk_module_configs: List of SDK Module config JSON files with SDK packages and versions.
- debug_key: Keystore that will later be used to sign the SDK APKs. It's expected to be a
+ sdk_archives: List of SDK archives, as ASAR files. They will also be listed as dependencies.
+ debug_key: Debug keystore that will later be used to sign the SDK APKs.
sandboxed_sdk_toolbox: Toolbox executable files.
host_javabase: Javabase used to run the toolbox.
"""
+ inputs = [debug_key]
args = ctx.actions.args()
args.add("generate-sdk-dependencies-manifest")
args.add("--manifest-package", manifest_package)
- args.add("--sdk-module-configs", ",".join([config.path for config in sdk_module_configs]))
+ if sdk_module_configs:
+ args.add("--sdk-module-configs", ",".join([config.path for config in sdk_module_configs]))
+ inputs.extend(sdk_module_configs)
+ if sdk_archives:
+ args.add("--sdk-archives", ",".join([archive.path for archive in sdk_archives]))
+ inputs.extend(sdk_archives)
args.add("--debug-keystore", debug_key)
args.add("--debug-keystore-pass", "android")
args.add("--debug-keystore-alias", "androiddebugkey")
@@ -158,7 +166,7 @@ def _generate_sdk_dependencies_manifest(
host_javabase = host_javabase,
executable = sandboxed_sdk_toolbox,
arguments = [args],
- inputs = sdk_module_configs + [debug_key],
+ inputs = inputs,
outputs = [output],
mnemonic = "GenSdkDepManifest",
progress_message = "Generate SDK dependencies manifest %s" % output.short_path,
diff --git a/src/tools/ak/rjar/rjar.go b/src/tools/ak/rjar/rjar.go
index c95dea8..fca8c76 100644
--- a/src/tools/ak/rjar/rjar.go
+++ b/src/tools/ak/rjar/rjar.go
@@ -240,6 +240,11 @@ func compileRJar(srcs []string, rjar, jdk, jartool string, targetLabel string) e
"--output", rjar,
}...)
if len(targetLabel) > 0 {
+ // Deal with "@//"-prefixed labels (in Bazel)
+ if strings.HasPrefix(targetLabel, "@//") {
+ targetLabel = strings.Replace(targetLabel, "@//", "//", 1)
+ }
+
args = append(args, []string{
"--target_label", targetLabel,
}...)
diff --git a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/config/SdkModulesConfigUtils.java b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/config/SdkModulesConfigUtils.java
deleted file mode 100644
index e023096..0000000
--- a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/config/SdkModulesConfigUtils.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2023 The Bazel Authors. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.devtools.build.android.sandboxedsdktoolbox.config;
-
-import com.android.bundle.SdkModulesConfigOuterClass.SdkModulesConfig;
-import com.android.tools.build.bundletool.model.RuntimeEnabledSdkVersionEncoder;
-import com.google.protobuf.util.JsonFormat;
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-/** Utilities for creating and extracting information from {@link SdkModulesConfig} messages. */
-public final class SdkModulesConfigUtils {
-
- public static SdkModulesConfig readFromJsonFile(Path configPath) {
- SdkModulesConfig.Builder builder = SdkModulesConfig.newBuilder();
- try {
- JsonFormat.parser().merge(Files.newBufferedReader(configPath), builder);
- return builder.build();
- } catch (IOException e) {
- throw new UncheckedIOException("Failed to parse SDK Module Config.", e);
- }
- }
-
- public static long getVersionMajor(SdkModulesConfig config) {
- return RuntimeEnabledSdkVersionEncoder.encodeSdkMajorAndMinorVersion(
- config.getSdkVersion().getMajor(), config.getSdkVersion().getMinor());
- }
-
- private SdkModulesConfigUtils() {}
-}
diff --git a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/config/BUILD b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/BUILD
index cbc3f38..4f8e336 100644
--- a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/config/BUILD
+++ b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/BUILD
@@ -1,4 +1,4 @@
-# Utilities for SDK module config proto message.
+# Utilities for extracting information from SDK archives and Bundle metadata.
package(
default_applicable_licenses = ["//:license"],
@@ -8,10 +8,11 @@ package(
licenses(["notice"])
java_library(
- name = "config",
+ name = "info",
srcs = glob(["*.java"]),
deps = [
"@rules_android_maven//:com_android_tools_build_bundletool",
+ "@rules_android_maven//:com_google_protobuf_protobuf_java",
"@rules_android_maven//:com_google_protobuf_protobuf_java_util",
],
)
diff --git a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/SdkInfo.java b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/SdkInfo.java
new file mode 100644
index 0000000..867e55d
--- /dev/null
+++ b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/SdkInfo.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2023 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.devtools.build.android.sandboxedsdktoolbox.info;
+
+import java.util.Objects;
+
+/**
+ * Information about a Sandboxed SDK. Used to define an SDK dependency and read from an SDK archive
+ * or bundle config.
+ */
+public final class SdkInfo {
+
+ private final String packageName;
+ private final long versionMajor;
+
+ SdkInfo(String packageName, long versionMajor) {
+ this.packageName = packageName;
+ this.versionMajor = versionMajor;
+ }
+
+ /** The SDK unique package name. */
+ public String getPackageName() {
+ return packageName;
+ }
+
+ /**
+ * The SDK versionMajor. This value is constructed from the full SDK version description and it
+ * represents the actual version of the SDK as used by the package manager later. The major and
+ * minor versions are merged and the patch version is ignored.
+ */
+ public long getVersionMajor() {
+ return versionMajor;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (object instanceof SdkInfo) {
+ SdkInfo that = (SdkInfo) object;
+ return this.packageName.equals(that.packageName) && this.versionMajor == that.versionMajor;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(packageName, versionMajor);
+ }
+}
diff --git a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/SdkInfoReader.java b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/SdkInfoReader.java
new file mode 100644
index 0000000..7efef66
--- /dev/null
+++ b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info/SdkInfoReader.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2023 The Bazel Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.devtools.build.android.sandboxedsdktoolbox.info;
+
+import com.android.bundle.SdkMetadataOuterClass.SdkMetadata;
+import com.android.bundle.SdkModulesConfigOuterClass.RuntimeEnabledSdkVersion;
+import com.android.bundle.SdkModulesConfigOuterClass.SdkModulesConfig;
+import com.android.tools.build.bundletool.model.RuntimeEnabledSdkVersionEncoder;
+import com.google.protobuf.ExtensionRegistry;
+import com.google.protobuf.util.JsonFormat;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.HashMap;
+
+/** Reads SDK information SDK archives and Bundle metadata files. */
+public final class SdkInfoReader {
+
+ // SDK metadata proto sits at the top level of an ASAR.
+ private static final String SDK_METADATA_ENTRY_PATH = "SdkMetadata.pb";
+
+ public static SdkInfo readFromSdkModuleJsonFile(Path sdkModulesConfigPath) {
+ SdkModulesConfig.Builder modulesConfig = SdkModulesConfig.newBuilder();
+ try {
+ JsonFormat.parser().merge(Files.newBufferedReader(sdkModulesConfigPath), modulesConfig);
+ return new SdkInfo(
+ modulesConfig.getSdkPackageName(), getVersionMajor(modulesConfig.getSdkVersion()));
+ } catch (IOException e) {
+ throw new UncheckedIOException("Failed to parse SDK Module Config.", e);
+ }
+ }
+
+ public static SdkInfo readFromSdkArchive(Path sdkArchivePath) {
+ URI uri = URI.create("jar:" + sdkArchivePath.toUri());
+ try (FileSystem zipfs = FileSystems.newFileSystem(uri, new HashMap<String, String>())) {
+ Path metadataInAsar = zipfs.getPath(SDK_METADATA_ENTRY_PATH);
+ if (!Files.exists(metadataInAsar)) {
+ throw new IllegalStateException(
+ String.format("Could not find %s in %s", SDK_METADATA_ENTRY_PATH, sdkArchivePath));
+ }
+ SdkMetadata metadata =
+ SdkMetadata.parseFrom(
+ Files.readAllBytes(metadataInAsar), ExtensionRegistry.getEmptyRegistry());
+ return new SdkInfo(metadata.getPackageName(), getVersionMajor(metadata.getSdkVersion()));
+ } catch (IOException e) {
+ throw new UncheckedIOException("Failed to extract SDK API descriptors.", e);
+ }
+ }
+
+ private static long getVersionMajor(RuntimeEnabledSdkVersion version) {
+ return RuntimeEnabledSdkVersionEncoder.encodeSdkMajorAndMinorVersion(
+ version.getMajor(), version.getMinor());
+ }
+
+ private SdkInfoReader() {}
+}
diff --git a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/AndroidManifestWriter.java b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/AndroidManifestWriter.java
index f840c5f..67ce730 100644
--- a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/AndroidManifestWriter.java
+++ b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/AndroidManifestWriter.java
@@ -15,10 +15,8 @@
*/
package com.google.devtools.build.android.sandboxedsdktoolbox.sdkdependenciesmanifest;
-import static com.google.devtools.build.android.sandboxedsdktoolbox.config.SdkModulesConfigUtils.getVersionMajor;
-
-import com.android.bundle.SdkModulesConfigOuterClass.SdkModulesConfig;
import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.android.sandboxedsdktoolbox.info.SdkInfo;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -50,7 +48,7 @@ final class AndroidManifestWriter {
static void writeManifest(
String packageName,
String certificateDigest,
- ImmutableSet<SdkModulesConfig> configs,
+ ImmutableSet<SdkInfo> infoSet,
Path outputPath) {
Document root = newEmptyDocument();
@@ -62,11 +60,11 @@ final class AndroidManifestWriter {
Element applicationNode = root.createElement(APPLICATION_ELEMENT_NAME);
manifestNode.appendChild(applicationNode);
- for (SdkModulesConfig config : configs) {
+ for (SdkInfo sdkInfo : infoSet) {
Element sdkDependencyElement = root.createElement(SDK_DEPENDENCY_ELEMENT_NAME);
- sdkDependencyElement.setAttribute(ANDROID_NAME_ATTRIBUTE, config.getSdkPackageName());
+ sdkDependencyElement.setAttribute(ANDROID_NAME_ATTRIBUTE, sdkInfo.getPackageName());
sdkDependencyElement.setAttribute(
- ANDROID_VERSION_MAJOR_ATTRIBUTE, Long.toString(getVersionMajor(config)));
+ ANDROID_VERSION_MAJOR_ATTRIBUTE, Long.toString(sdkInfo.getVersionMajor()));
sdkDependencyElement.setAttribute(ANDROID_CERTIFICATE_DIGEST_ATTRIBUTE, certificateDigest);
applicationNode.appendChild(sdkDependencyElement);
}
diff --git a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/BUILD b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/BUILD
index b2584b2..12a7a1b 100644
--- a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/BUILD
+++ b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/BUILD
@@ -11,7 +11,7 @@ java_library(
name = "sdkdependenciesmanifest",
srcs = glob(["*.java"]),
deps = [
- "//src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/config",
+ "//src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/info",
"@rules_android_maven//:com_android_tools_build_bundletool",
"@rules_android_maven//:com_google_guava_guava",
"@rules_android_maven//:info_picocli_picocli",
diff --git a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/GenerateSdkDependenciesManifestCommand.java b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/GenerateSdkDependenciesManifestCommand.java
index c390f27..354f8fe 100644
--- a/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/GenerateSdkDependenciesManifestCommand.java
+++ b/src/tools/java/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/GenerateSdkDependenciesManifestCommand.java
@@ -18,12 +18,14 @@ package com.google.devtools.build.android.sandboxedsdktoolbox.sdkdependenciesman
import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.devtools.build.android.sandboxedsdktoolbox.sdkdependenciesmanifest.AndroidManifestWriter.writeManifest;
import static com.google.devtools.build.android.sandboxedsdktoolbox.sdkdependenciesmanifest.CertificateDigestGenerator.generateCertificateDigest;
-import static java.util.Arrays.stream;
-import com.android.bundle.SdkModulesConfigOuterClass.SdkModulesConfig;
import com.google.common.collect.ImmutableSet;
-import com.google.devtools.build.android.sandboxedsdktoolbox.config.SdkModulesConfigUtils;
+import com.google.devtools.build.android.sandboxedsdktoolbox.info.SdkInfo;
+import com.google.devtools.build.android.sandboxedsdktoolbox.info.SdkInfoReader;
import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
@@ -31,15 +33,18 @@ import picocli.CommandLine.Option;
@Command(
name = "generate-sdk-dependencies-manifest",
description =
- "Generates an Android manifest with the <uses-sdk-library> tags from the given "
- + "SDK bundles.")
+ "Generates an Android manifest with <uses-sdk-library> tags from the given SDK bundles "
+ + "or archives.")
public final class GenerateSdkDependenciesManifestCommand implements Runnable {
@Option(names = "--manifest-package", required = true)
String manifestPackage;
- @Option(names = "--sdk-module-configs", split = ",", required = true)
- Path[] sdkModuleConfigPaths;
+ @Option(names = "--sdk-module-configs", split = ",", required = false)
+ List<Path> sdkModuleConfigPaths = new ArrayList<>();
+
+ @Option(names = "--sdk-archives", split = ",", required = false)
+ List<Path> sdkArchivePaths = new ArrayList<>();
@Option(names = "--debug-keystore", required = true)
Path debugKeystorePath;
@@ -55,9 +60,15 @@ public final class GenerateSdkDependenciesManifestCommand implements Runnable {
@Override
public void run() {
- ImmutableSet<SdkModulesConfig> configSet =
- stream(sdkModuleConfigPaths)
- .map(SdkModulesConfigUtils::readFromJsonFile)
+ if (sdkModuleConfigPaths.isEmpty() && sdkArchivePaths.isEmpty()) {
+ throw new IllegalArgumentException(
+ "At least one of --sdk-module-configs or --sdk-archives must be specified.");
+ }
+
+ ImmutableSet<SdkInfo> configSet =
+ Stream.concat(
+ sdkModuleConfigPaths.stream().map(SdkInfoReader::readFromSdkModuleJsonFile),
+ sdkArchivePaths.stream().map(SdkInfoReader::readFromSdkArchive))
.collect(toImmutableSet());
String certificateDigest =
diff --git a/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/BUILD b/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/BUILD
index c2b38d1..84d1663 100644
--- a/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/BUILD
+++ b/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/BUILD
@@ -11,16 +11,12 @@ java_test(
name = "GenerateSdkDependenciesManifestCommandTest",
size = "small",
srcs = ["GenerateSdkDependenciesManifestCommandTest.java"],
- data = [
- "testdata/com.example.firstsdkconfig.json",
- "testdata/com.example.secondsdkconfig.json",
- "testdata/expected_manifest_multiple_sdks.xml",
- "testdata/expected_manifest_single_sdk.xml",
- "testdata/test_key",
- ],
+ data = glob(["testdata/*"]),
deps = [
"//src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/utils",
- "@rules_android_maven//:junit_junit",
+ "@rules_android_maven//:com_android_tools_build_bundletool",
+ "@rules_android_maven//:com_google_protobuf_protobuf_java_util",
"@rules_android_maven//:com_google_truth_truth",
+ "@rules_android_maven//:junit_junit",
],
)
diff --git a/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/GenerateSdkDependenciesManifestCommandTest.java b/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/GenerateSdkDependenciesManifestCommandTest.java
index 7dc04e7..749320e 100644
--- a/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/GenerateSdkDependenciesManifestCommandTest.java
+++ b/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/GenerateSdkDependenciesManifestCommandTest.java
@@ -19,8 +19,13 @@ import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.android.sandboxedsdktoolbox.utils.Runner.runCommand;
import static com.google.devtools.build.android.sandboxedsdktoolbox.utils.TestData.JAVATESTS_DIR;
import static com.google.devtools.build.android.sandboxedsdktoolbox.utils.TestData.readFromAbsolutePath;
+import static com.google.devtools.build.android.sandboxedsdktoolbox.utils.Zip.createZipWithSingleEntry;
+import com.android.bundle.SdkMetadataOuterClass.SdkMetadata;
import com.google.devtools.build.android.sandboxedsdktoolbox.utils.CommandResult;
+import com.google.protobuf.util.JsonFormat;
+import java.io.IOException;
+import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.Rule;
import org.junit.Test;
@@ -42,6 +47,9 @@ public final class GenerateSdkDependenciesManifestCommandTest {
TEST_DATA_DIR.resolve("com.example.firstsdkconfig.json");
private static final Path SECOND_SDK_CONFIG_JSON_PATH =
TEST_DATA_DIR.resolve("com.example.secondsdkconfig.json");
+ private static final Path ARCHIVE_CONFIG_JSON_PATH =
+ TEST_DATA_DIR.resolve("com.example.archivedsdkmetadata.json");
+
/*
The test key was generated with this command, its password is "android"
keytool -genkeypair \
@@ -109,4 +117,43 @@ public final class GenerateSdkDependenciesManifestCommandTest {
.isEqualTo(
readFromAbsolutePath(TEST_DATA_DIR.resolve("expected_manifest_multiple_sdks.xml")));
}
+
+ @Test
+ public void generateManifest_forSdksAndArchives_success() throws Exception {
+ String manifestPackage = "com.example.generatedmanifest";
+ // Create a zip with a single file containing the SdkMetadata proto message, serialized.
+ Path archiveConfigPath = testFolder.getRoot().toPath().resolve("sdk.asar");
+ createZipWithSingleEntry(archiveConfigPath, "SdkMetadata.pb", readSdkMetadata().toByteArray());
+ Path outputFile = testFolder.newFile().toPath();
+
+ CommandResult result =
+ runCommand(
+ "generate-sdk-dependencies-manifest",
+ "--manifest-package",
+ manifestPackage,
+ "--sdk-module-configs",
+ FIRST_SDK_CONFIG_JSON_PATH.toString(),
+ "--sdk-archives",
+ archiveConfigPath.toString(),
+ "--debug-keystore",
+ TEST_KEY_PATH.toString(),
+ "--debug-keystore-pass",
+ "android",
+ "--debug-keystore-alias",
+ "androiddebugkey",
+ "--output-manifest",
+ outputFile.toString());
+
+ assertThat(result.getStatusCode()).isEqualTo(0);
+ assertThat(result.getOutput()).isEmpty();
+ assertThat(readFromAbsolutePath(outputFile))
+ .isEqualTo(
+ readFromAbsolutePath(TEST_DATA_DIR.resolve("expected_manifest_with_archived_sdk.xml")));
+ }
+
+ private static SdkMetadata readSdkMetadata() throws IOException {
+ SdkMetadata.Builder metadata = SdkMetadata.newBuilder();
+ JsonFormat.parser().merge(Files.newBufferedReader(ARCHIVE_CONFIG_JSON_PATH), metadata);
+ return metadata.build();
+ }
}
diff --git a/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/testdata/com.example.archivedsdkmetadata.json b/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/testdata/com.example.archivedsdkmetadata.json
new file mode 100644
index 0000000..d3be443
--- /dev/null
+++ b/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/testdata/com.example.archivedsdkmetadata.json
@@ -0,0 +1,11 @@
+{
+ "package_name": "com.example.archivedsdk",
+ "sdk_version": {
+ "major": 33,
+ "minor": 2,
+ "patch": 1
+ },
+
+ // We always use the debug key digest instead of the one provided in the ASAR.
+ "certificate_digest": "fake digest that should be ignored."
+} \ No newline at end of file
diff --git a/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/testdata/expected_manifest_with_archived_sdk.xml b/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/testdata/expected_manifest_with_archived_sdk.xml
new file mode 100644
index 0000000..e3bab8f
--- /dev/null
+++ b/src/tools/javatests/com/google/devtools/build/android/sandboxedsdktoolbox/sdkdependenciesmanifest/testdata/expected_manifest_with_archived_sdk.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.generatedmanifest">
+ <application>
+ <uses-sdk-library android:certDigest="91:8E:A3:7D:7D:D0:E0:A0:14:9F:21:28:83:95:8A:F0:80:E6:F9:7B:4D:5A:39:01:76:02:E8:2D:7D:FF:A9:10" android:name="com.example.firstsdkconfig" android:versionMajor="20003"/>
+ <uses-sdk-library android:certDigest="91:8E:A3:7D:7D:D0:E0:A0:14:9F:21:28:83:95:8A:F0:80:E6:F9:7B:4D:5A:39:01:76:02:E8:2D:7D:FF:A9:10" android:name="com.example.archivedsdk" android:versionMajor="330002"/>
+ </application>
+</manifest> \ No newline at end of file
diff --git a/src/tools/mi/deployment_oss/BUILD b/src/tools/mi/deployment_oss/BUILD
new file mode 100644
index 0000000..b078ff2
--- /dev/null
+++ b/src/tools/mi/deployment_oss/BUILD
@@ -0,0 +1,36 @@
+load("@bazel_skylib//rules:build_test.bzl", "build_test")
+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
+
+package(
+ default_applicable_licenses = ["//:license"],
+ default_visibility = ["//src/tools/mi/deployment_oss:__pkg__"],
+)
+
+go_binary(
+ name = "deploy_binary",
+ srcs = ["deploy_binary.go"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "//src/common/golang:flagfile",
+ "//src/common/golang:flags",
+ "//src/common/golang:pprint",
+ "//src/tools/mi/deployment_oss:deployment",
+ "@com_github_golang_glog//:glog",
+ ],
+)
+
+go_library(
+ name = "deployment",
+ importpath = "src/tools/mi/deployment_oss/deployment",
+
+ srcs = [
+ "deploy.go",
+ ],
+ visibility = ["//src/tools/mi:__subpackages__"],
+ deps = ["//src/common/golang:pprint"],
+)
+
+build_test(
+ name = "deploy_binary_build_test",
+ targets = [":deploy_binary"]
+) \ No newline at end of file
diff --git a/src/tools/mi/deployment_oss/deploy.go b/src/tools/mi/deployment_oss/deploy.go
new file mode 100644
index 0000000..1446e58
--- /dev/null
+++ b/src/tools/mi/deployment_oss/deploy.go
@@ -0,0 +1,64 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// 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 deployment has utilities to sync mobile-install build outputs with a device.
+package deployment
+
+import (
+ "context"
+ "fmt"
+ "os"
+ "os/exec"
+ "strconv"
+
+ "src/common/golang/pprint"
+)
+
+// AndroidStudioSync calls to the Studio deployer with splits.
+func AndroidStudioSync(ctx context.Context, deviceSerial, port, pkg string, splits []string, deployer, adbPath, jdk string, optimisticInstall bool, studioVerboseLog bool, userID int, useADBRoot bool) error {
+ args := []string{"-jar", deployer, "install", pkg}
+ if deviceSerial != "" {
+ args = append(args, fmt.Sprintf("--device=%s", deviceSerial))
+ }
+ args = append(args, "--skip-post-install", "--no-jdwp-client-support")
+ if optimisticInstall {
+ args = append(args, "--optimistic-install")
+ }
+ if useADBRoot {
+ args = append(args, "--use-root-push-install")
+ }
+ if studioVerboseLog {
+ args = append(args, "--log-level=VERBOSE")
+ }
+ if adbPath != "" {
+ args = append(args, fmt.Sprintf("--adb=%s", adbPath))
+ }
+ if userID != 0 {
+ args = append(args, fmt.Sprintf("--user=%s", strconv.Itoa(userID)))
+ }
+ args = append(args, splits...)
+ cmd := exec.Command(jdk, args...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if port != "" {
+ cmd.Env = append(os.Environ(), fmt.Sprintf("ANDROID_ADB_SERVER_PORT=%s", port))
+ }
+ if studioVerboseLog {
+ pprint.Info("device: %s", deviceSerial)
+ pprint.Info("port: %s", port)
+ pprint.Info("Env: %s", cmd.Env)
+ pprint.Info("Cmd: %s", cmd.String())
+ }
+ return cmd.Run()
+}
diff --git a/src/tools/mi/deployment_oss/deploy_binary.go b/src/tools/mi/deployment_oss/deploy_binary.go
new file mode 100644
index 0000000..503c81a
--- /dev/null
+++ b/src/tools/mi/deployment_oss/deploy_binary.go
@@ -0,0 +1,217 @@
+// Copyright 2018 The Bazel Authors. All rights reserved.
+//
+// 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.
+
+// The deploy_binary command unpacks a workspace and deploys it to a device.
+package main
+
+import (
+ "context"
+ "flag"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "strings"
+ "time"
+
+ glog "github.com/golang/glog"
+
+ _ "src/common/golang/flagfile"
+ "src/common/golang/flags"
+ "src/common/golang/pprint"
+ "src/tools/mi/deployment_oss/deployment"
+)
+
+var (
+ adbArgs = flags.NewStringList("adb_arg", "Options for the adb binary.")
+ adbPath = flag.String("adb", "/usr/bin/adb", "Path to the adb binary to use with mobile-install.")
+ device = flag.String("device", "", "The adb device serial number.")
+ javaHome = flag.String("java_home", "", "Path to JDK.")
+ launchActivity = flag.String("launch_activity", "", "Activity to launch via am start -n package/.activity_to_launch.")
+ appPackagePath = flag.String("manifest_package_name_path", "", "Path to file containing the manifest package name.")
+ splits = flags.NewStringList("splits", "The list of split apk paths.")
+ start = flag.String("start", "", "start_type from mobile-install.")
+ startType = flag.String("start_type", "", "start_type (deprecated, use --start).")
+ useADBRoot = flag.Bool("use_adb_root", true, "whether (true) or not (false) to use root permissions.")
+ userID = flag.Int("user", 0, "User id to install the app for.")
+
+ // Studio deployer args
+ studioDeployerPath = flag.String("studio_deployer", "", "Path to the Android Studio deployer.")
+ optimisticInstall = flag.Bool("optimistic-install", false, "If true, try to push changes to the device without installing.")
+ studioVerboseLog = flag.Bool("studio-verbose-log", false, "If true, enable verbose logging for the Android Studio deployer")
+
+ // Need to double up on launch_app due as the built-in flag module does not support noXX for bool flags.
+ // Some users are using --nolaunch_app, so we need to explicitly declare this flag
+ launchApp = flag.Bool("launch_app", true, "Launch the app after the sync is done.")
+ noLaunchApp = flag.Bool("nolaunch_app", false, "Don't launch the app after the sync is done.")
+ noDeploy = flag.Bool("nodeploy", false, "Don't deploy or launch the app, useful for testing.")
+
+ // Unused flags: Relevant only for Google-internal use cases, but need to exist in the flag parser
+ buildID = flag.String("build_id", "", "The id of the build. Set by Bazel, the user should not use this flag.")
+)
+
+func resolveDeviceSerialAndPort(ctx context.Context, device string) (deviceSerialFlag, port string) {
+ switch {
+ case strings.Contains(device, ":tcp:"):
+ parts := strings.SplitN(device, ":tcp:", 2)
+ deviceSerialFlag = parts[0]
+ port = parts[1]
+ case strings.HasPrefix(device, "tcp:"):
+ port = strings.TrimPrefix(device, "tcp:")
+ default:
+ deviceSerialFlag = device
+ }
+ return deviceSerialFlag, port
+}
+
+func determineDeviceSerial(deviceSerialFlag, deviceSerialEnv, deviceSerialADBArg string) string {
+ var deviceSerial string
+ switch {
+ case deviceSerialFlag != "":
+ deviceSerial = deviceSerialFlag
+ case deviceSerialEnv != "":
+ deviceSerial = deviceSerialEnv
+ case deviceSerialADBArg != "":
+ deviceSerial = deviceSerialADBArg
+ }
+ return deviceSerial
+}
+
+// ReadFile reads file from a given path
+func readFile(path string) []byte {
+ data, err := ioutil.ReadFile(path)
+ if err != nil {
+ log.Fatalf("Error reading file %q: %v", path, err)
+ }
+ return data
+}
+
+func parseRepeatedFlag(n string, a *flags.StringList) {
+ var l []string
+ for _, f := range os.Args {
+ if strings.HasPrefix(f, n) {
+ l = append(l, strings.TrimPrefix(f, n))
+ }
+ }
+ if len(l) > 1 {
+ *a = l
+ }
+}
+
+// Flush all the metrics to Streamz before the program exits.
+func flushAndExitf(ctx context.Context, unused1, unused2, unused3, unused4, format string, args ...any) {
+ glog.Exitf(format, args...)
+}
+
+func main() {
+ ctx := context.Background()
+
+ flag.Parse()
+
+ pprint.Info("Deploying using OSS mobile-install!")
+
+ if *noDeploy {
+ pprint.Warning("--nodeploy set, not deploying application.")
+ return
+ }
+
+ // Override --launch_app if --nolaunch_app is passed
+ if *noLaunchApp {
+ *launchApp = false
+ }
+
+ if *appPackagePath == "" {
+ glog.Exitf("--manifest_package_name is required")
+ }
+
+ // Resolve the device serial and port.
+ var deviceSerialFlag, port string
+ if *device != "" {
+ deviceSerialFlag, port = resolveDeviceSerialAndPort(ctx, *device)
+ }
+ deviceSerialEnv := os.Getenv("ANDROID_SERIAL")
+
+ // TODO(b/66490815): Remove once adb_arg flag is deprecated.
+ // Check for a device serial in adb_arg. If deviceSerial has not been specified, the value
+ // found here will become the deviceSerial. If the deviceSerial has been specified the value
+ // found here will be ignored but we will notify the user the device chosen.
+ var deviceSerialADBArg string
+ for i, arg := range *adbArgs {
+ if strings.TrimSpace(arg) == "-s" && len(*adbArgs) > i+1 {
+ deviceSerialADBArg = (*adbArgs)[i+1]
+ }
+ }
+
+ // TODO(timpeut): Delete after the next blaze release
+ // Ignore the device passed by --adb_arg if it matches the device passed by --device.
+ if deviceSerialADBArg == *device {
+ deviceSerialADBArg = ""
+ }
+
+ // Determine which value to use as the deviceSerial.
+ deviceSerial := determineDeviceSerial(deviceSerialFlag, deviceSerialEnv, deviceSerialADBArg)
+
+ // Warn user of the multiple device serial specification, that is not equal to the first.
+ if (deviceSerialEnv != "" && deviceSerialEnv != deviceSerial) ||
+ (deviceSerialADBArg != "" && deviceSerialADBArg != deviceSerial) {
+ pprint.Warning("A device serial was specified more than once with --device, $ANDROID_SERIAL or --adb_arg, using %s.", deviceSerial)
+ }
+
+ appPackage := strings.TrimSpace(string(readFile(*appPackagePath)))
+
+ startTime := time.Now()
+
+ pprint.Info("Installing application using the Android Studio deployer ...")
+ if err := deployment.AndroidStudioSync(ctx, deviceSerial, port, appPackage, *splits, *studioDeployerPath, *adbPath, *javaHome, *optimisticInstall, *studioVerboseLog, *userID, *useADBRoot); err != nil {
+ flushAndExitf(ctx, "", "", "", "", "Got error installing using the Android Studio deployer: %v", err)
+ }
+
+ deploymentTime := time.Since(startTime)
+ pprint.Info("Took %.2f seconds to sync changes", deploymentTime.Seconds())
+
+ if *startType != "" {
+ *start = *startType
+ }
+
+ // Wait for the debugger if debug mode selected
+ if *start == "DEBUG" {
+ waitCmd := exec.Command(*adbPath, "shell", "am", "set-debug-app", "-w", appPackage)
+ if err := waitCmd.Wait(); err != nil {
+ pprint.Error("Unable to wait for debugger: %s", err.Error())
+ }
+ }
+
+ if *launchApp {
+ pprint.Info("Finished deploying changes. Launching app")
+ var launchCmd *exec.Cmd
+ if *launchActivity != "" {
+ launchCmd = exec.Command(*adbPath, "shell", "am", "start", "-a", "android.intent.action.MAIN", "-n", appPackage+"/"+*launchActivity)
+ } else {
+ launchCmd = exec.Command(*adbPath, "shell", "monkey", "-p", appPackage, "1")
+ pprint.Warning(
+ "No or multiple main activities found, falling back to Monkey launcher. Specify the activity you want with `-- --launch_activity` or `-- --nolaunch_app` to launch nothing.")
+ }
+
+ if err := launchCmd.Run(); err != nil {
+ pprint.Warning("Unable to launch app. Specify an activity with --launch_activity.")
+ pprint.Warning("Original error: %s", err.Error())
+ }
+ } else {
+ // Always stop the app since classloader needs to be reloaded.
+ stopCmd := exec.Command(*adbPath, "shell", "am", "force-stop", appPackage)
+ if err := stopCmd.Run(); err != nil {
+ pprint.Error("Unable to stop app: %s", err.Error())
+ }
+ }
+}
diff --git a/test/rules/android_binary_internal/r8_integration/java/com/basicapp/BUILD b/test/rules/android_binary_internal/r8_integration/java/com/basicapp/BUILD
index 4727887..a164ae6 100644
--- a/test/rules/android_binary_internal/r8_integration/java/com/basicapp/BUILD
+++ b/test/rules/android_binary_internal/r8_integration/java/com/basicapp/BUILD
@@ -4,8 +4,15 @@ load("//rules:rules.bzl", "android_binary", "android_library")
android_binary(
name = name,
srcs = ["BasicActivity.java"],
+ # Work around --java_runtime_version=17 and --java_language_version=11
+ # set in the presubmit tests.
+ javacopts = [
+ "-target",
+ "8",
+ "-source",
+ "8",
+ ],
manifest = "AndroidManifest.xml",
- min_sdk_version = 27,
proguard_specs = specs,
resource_files = glob(["res/**"]),
shrink_resources = shrink,
@@ -14,9 +21,6 @@ load("//rules:rules.bzl", "android_binary", "android_library")
":basic_lib",
":lib_with_specs",
],
- # Work around --java_runtime_version=17 and --java_language_version=11
- # set in the presubmit tests.
- javacopts = ["-target", "8", "-source", "8"],
)
for name, specs, shrink in [
(
diff --git a/test/rules/android_library_extensibility/BUILD b/test/rules/android_library_extensibility/BUILD
new file mode 100644
index 0000000..99706ce
--- /dev/null
+++ b/test/rules/android_library_extensibility/BUILD
@@ -0,0 +1,28 @@
+load(":custom_android_library.bzl", "custom_android_library")
+load(":test.bzl", "custom_android_library_test")
+
+package(
+ default_applicable_licenses = ["//:license"],
+ default_visibility =
+ ["//:__subpackages__"],
+)
+
+licenses(["notice"])
+
+custom_android_library(
+ name = "custom_android_library",
+ testonly = True,
+ key = "test_key",
+)
+
+custom_android_library_test(
+ name = "custom_android_library_test",
+ lib = ":custom_android_library",
+)
+
+test_suite(
+ name = "integration_tests",
+ tests = [
+ ":custom_android_library_test",
+ ],
+)
diff --git a/test/rules/android_library_extensibility/custom_android_library.bzl b/test/rules/android_library_extensibility/custom_android_library.bzl
new file mode 100644
index 0000000..a58fd1e
--- /dev/null
+++ b/test/rules/android_library_extensibility/custom_android_library.bzl
@@ -0,0 +1,86 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+"""Custom android_library for use in test.bzl"""
+
+load(
+ "//rules:attrs.bzl",
+ _attrs = "attrs",
+)
+load(
+ "//rules:java.bzl",
+ _java = "java",
+)
+load(
+ "//rules:processing_pipeline.bzl",
+ _ProviderInfo = "ProviderInfo",
+ _processing_pipeline = "processing_pipeline",
+)
+load(
+ "//rules/android_library:attrs.bzl",
+ _BASE_ATTRS = "ATTRS",
+)
+load(
+ "//rules/android_library:impl.bzl",
+ _BASE_PROCESSORS = "PROCESSORS",
+ _finalize = "finalize",
+)
+load(
+ "//rules/android_library:rule.bzl",
+ _make_rule = "make_rule",
+)
+
+CustomProviderInfo = provider(
+ doc = "Custom provider to provide",
+ fields = dict(
+ key = "Some key to provide",
+ ),
+)
+
+def _process_custom_provider(ctx, **_unused_sub_ctxs):
+ return _ProviderInfo(
+ name = "custom_provider_ctx",
+ value = struct(
+ providers = [
+ CustomProviderInfo(
+ key = ctx.attr.key,
+ ),
+ ],
+ ),
+ )
+
+PROCESSORS = _processing_pipeline.append(
+ _BASE_PROCESSORS,
+ CustomProviderInfoProcessor = _process_custom_provider,
+)
+
+_PROCESSING_PIPELINE = _processing_pipeline.make_processing_pipeline(
+ processors = PROCESSORS,
+ finalize = _finalize,
+)
+
+def _impl(ctx):
+ java_package = _java.resolve_package_from_label(ctx.label, ctx.attr.custom_package)
+ return _processing_pipeline.run(ctx, java_package, _PROCESSING_PIPELINE)
+
+custom_android_library = _make_rule(
+ implementation = _impl,
+ attrs = _attrs.add(_BASE_ATTRS, dict(
+ # Custom attribute to wrap in a provider
+ key = attr.string(),
+ )),
+ additional_providers = [
+ CustomProviderInfo,
+ ],
+)
diff --git a/test/rules/android_library_extensibility/test.bzl b/test/rules/android_library_extensibility/test.bzl
new file mode 100644
index 0000000..78aa9c1
--- /dev/null
+++ b/test/rules/android_library_extensibility/test.bzl
@@ -0,0 +1,41 @@
+# Copyright 2023 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+"""Tests for the extensibility functionality of android_library."""
+
+load(
+ "//test/utils:lib.bzl",
+ "asserts",
+ "unittest",
+)
+load(
+ ":custom_android_library.bzl",
+ "CustomProviderInfo",
+)
+
+def custom_android_library_test_impl(ctx):
+ env = unittest.begin(ctx)
+
+ # Assert that the custom provider exists
+ asserts.true(env, CustomProviderInfo in ctx.attr.lib)
+ asserts.equals(env, ctx.attr.lib[CustomProviderInfo].key, "test_key")
+
+ return unittest.end(env)
+
+custom_android_library_test = unittest.make(
+ impl = custom_android_library_test_impl,
+ attrs = {
+ "lib": attr.label(providers = [CustomProviderInfo]),
+ },
+)
diff --git a/test/rules/android_local_test/BUILD b/test/rules/android_local_test/BUILD
new file mode 100644
index 0000000..590a523
--- /dev/null
+++ b/test/rules/android_local_test/BUILD
@@ -0,0 +1,69 @@
+load("//rules:rules.bzl", "android_local_test")
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+load(":java_launcher_integration_test.bzl", "android_local_test_launcher_integration_test_suite")
+load(":java_launcher_test.bzl", "android_local_test_launcher_test_suite")
+
+package(
+ default_applicable_licenses = ["//:license"],
+ default_visibility = ["//visibility:public"],
+)
+
+licenses(["notice"])
+
+exports_files([
+ "EmptyTest.java",
+ "integration_test_stub_script.sh",
+])
+
+bzl_library(
+ name = "bzl",
+ srcs = glob(["*.bzl"]),
+ visibility = ["//visibility:private"],
+)
+
+android_local_test(
+ name = "sample_test_default_launcher",
+ srcs = ["EmptyTest.java"],
+ custom_package = "com.google.android.emptytest",
+ test_class = "com.google.android.emptytest.EmptyTest",
+ deps = [
+ "@robolectric//bazel:android-all",
+ "@rules_android_maven//:androidx_test_ext_junit",
+ "@rules_android_maven//:junit_junit",
+ ],
+)
+
+android_local_test(
+ name = "sample_test_default_launcher_integration",
+ srcs = ["EmptyTest.java"],
+ custom_package = "com.google.android.emptytest",
+ test_class = "com.google.android.emptytest.EmptyTest",
+ deps = [
+ "@robolectric//bazel:android-all",
+ "@rules_android_maven//:androidx_test_ext_junit",
+ "@rules_android_maven//:junit_junit",
+ ],
+)
+
+config_setting(
+ name = "jdk17",
+ values = {
+ "java_runtime_version": "17",
+ },
+)
+
+android_local_test_launcher_test_suite(
+ name = "android_local_test_launcher_tests",
+ expected_executable = select({
+ ":jdk17": "../remotejdk17_linux/bin/java",
+ "//conditions:default": "third_party/java/jdk/jdk-sts-k8/bin/java",
+ }),
+)
+
+android_local_test_launcher_integration_test_suite(
+ name = "android_local_test_launcher_integration_tests",
+ expected_executable = select({
+ ":jdk17": "rules_android/../remotejdk17_linux/bin/java",
+ "//conditions:default": "rules_android/third_party/java/jdk/jdk-sts-k8/bin/java",
+ }),
+)
diff --git a/test/rules/android_local_test/EmptyTest.java b/test/rules/android_local_test/EmptyTest.java
new file mode 100644
index 0000000..8f85825
--- /dev/null
+++ b/test/rules/android_local_test/EmptyTest.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright 2021 The Bazel Authors. All rights reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.android.emptytest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class EmptyTest {
+ @Test
+ public void emptyTest() {
+ }
+}
diff --git a/test/rules/android_local_test/integration_test_stub_script.sh b/test/rules/android_local_test/integration_test_stub_script.sh
new file mode 100644
index 0000000..9f836f2
--- /dev/null
+++ b/test/rules/android_local_test/integration_test_stub_script.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+# Copyright 2021 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+exit_with_error() {
+ echo "Expected to find JAVABIN=\${JAVABIN:-\${JAVA_RUNFILES}/%expected_executable% but was"
+ echo $reference
+ exit 1
+}
+
+executable="%executable%"
+reference=`grep -o 'JAVABIN=\\${JAVABIN:-\\${JAVA_RUNFILES}/.*}' $executable`
+grep -c "JAVABIN:-\${JAVA_RUNFILES}/%expected_executable%" $executable >> /dev/null || exit_with_error
diff --git a/test/rules/android_local_test/java/com/starlark_resources/AndroidManifest.xml b/test/rules/android_local_test/java/com/starlark_resources/AndroidManifest.xml
new file mode 100644
index 0000000..978e2c8
--- /dev/null
+++ b/test/rules/android_local_test/java/com/starlark_resources/AndroidManifest.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.starlark_resources">
+ <uses-sdk
+ android:minSdkVersion="21"
+ android:targetSdkVersion="24" />
+</manifest>
diff --git a/test/rules/android_local_test/java/com/starlark_resources/BUILD b/test/rules/android_local_test/java/com/starlark_resources/BUILD
new file mode 100644
index 0000000..f5824cd
--- /dev/null
+++ b/test/rules/android_local_test/java/com/starlark_resources/BUILD
@@ -0,0 +1,177 @@
+# Tests that run on head android_local_test rule to verify Starlark resource processing pipeline.
+
+load(
+ "//rules:rules.bzl",
+ "android_library",
+ "android_local_test",
+)
+load(
+ "//test/rules/android_local_test:test.bzl",
+ "rule_test",
+)
+
+package(
+ default_applicable_licenses = ["//:license"],
+ default_visibility = ["//visibility:private"],
+)
+
+licenses(["notice"])
+
+android_local_test(
+ name = "no_deps_with_resources",
+ srcs = ["SampleTest.java"],
+ manifest = "AndroidManifest.xml",
+ resource_files = glob(["res/**"]),
+ test_class = "com.starlark_resources.SampleTest",
+ deps = [
+ "@robolectric//bazel:android-all",
+ "@rules_android_maven//:androidx_test_core",
+ "@rules_android_maven//:androidx_test_ext_junit",
+ "@rules_android_maven//:junit_junit",
+ "@rules_android_maven//:org_robolectric_robolectric",
+ ],
+)
+
+rule_test(
+ name = "no_deps_with_resources_rule_test",
+ target_under_test = ":no_deps_with_resources",
+)
+
+# TODO(b/161179595): Add test to exercise resource_configuration_filter wiring.
+
+# TODO(aarmin): Add test to exercise densities and manifest_values wiring.
+
+android_library(
+ name = "resource_processing",
+ assets = ["assets/bar.txt"],
+ assets_dir = "assets",
+ manifest = "AndroidManifest.xml",
+ resource_files = glob(["res/**"]),
+)
+
+android_local_test(
+ name = "single_resource_dep_without_manifest",
+ srcs = ["SampleTest.java"],
+ test_class = "com.starlark_resources.SampleTest",
+ deps = [
+ ":resource_processing",
+ "@robolectric//bazel:android-all",
+ "@rules_android_maven//:androidx_test_core",
+ "@rules_android_maven//:androidx_test_ext_junit",
+ "@rules_android_maven//:junit_junit",
+ "@rules_android_maven//:org_robolectric_robolectric",
+ ],
+)
+
+rule_test(
+ name = "single_resource_dep_without_manifest_rule_test",
+ target_under_test = ":single_resource_dep_without_manifest",
+)
+
+android_local_test(
+ name = "single_resource_dep",
+ srcs = ["SampleTest.java"],
+ manifest = "AndroidManifest.xml",
+ test_class = "com.starlark_resources.SampleTest",
+ deps = [
+ ":resource_processing",
+ "@robolectric//bazel:android-all",
+ "@rules_android_maven//:androidx_test_core",
+ "@rules_android_maven//:androidx_test_ext_junit",
+ "@rules_android_maven//:junit_junit",
+ "@rules_android_maven//:org_robolectric_robolectric",
+ ],
+)
+
+rule_test(
+ name = "single_resource_dep_rule_test",
+ target_under_test = ":single_resource_dep",
+)
+
+android_library(
+ name = "resources_with_dep_with_res",
+ assets = ["assets/foo.txt"],
+ assets_dir = "assets",
+ manifest = "AndroidManifest.xml",
+ resource_files = glob(["another_res/**"]),
+ deps = [":resource_processing"],
+)
+
+android_local_test(
+ name = "multiple_resource_deps",
+ srcs = ["SampleTestMultipleDeps.java"],
+ manifest = "AndroidManifest.xml",
+ test_class = "com.starlark_resources.SampleTestMultipleDeps",
+ deps = [
+ ":resources_with_dep_with_res",
+ "@robolectric//bazel:android-all",
+ "@rules_android_maven//:androidx_test_core",
+ "@rules_android_maven//:androidx_test_ext_junit",
+ "@rules_android_maven//:junit_junit",
+ "@rules_android_maven//:org_robolectric_robolectric",
+ ],
+)
+
+rule_test(
+ name = "multiple_resource_deps_rule_test",
+ target_under_test = ":multiple_resource_deps",
+)
+
+android_library(
+ name = "resource_processing_with_neverlink",
+ manifest = "AndroidManifest.xml",
+ neverlink = True,
+ resource_files = glob(["res/**"]),
+)
+
+android_local_test(
+ name = "depends_on_neverlink_lib",
+ srcs = ["SampleTestNeverlinkDep.java"],
+ manifest = "AndroidManifest.xml",
+ test_class = "com.starlark_resources.SampleTestNeverlinkDep",
+ deps = [
+ ":resource_processing_with_neverlink",
+ "@robolectric//bazel:android-all",
+ "@rules_android_maven//:androidx_test_core",
+ "@rules_android_maven//:androidx_test_ext_junit",
+ "@rules_android_maven//:junit_junit",
+ "@rules_android_maven//:org_robolectric_robolectric",
+ ],
+)
+
+rule_test(
+ name = "depends_on_neverlink_lib_rule_test",
+ expect_resources = False,
+ target_under_test = ":depends_on_neverlink_lib",
+)
+
+android_local_test(
+ name = "manifest_values_low_minsdk",
+ srcs = ["SampleTest.java"],
+ manifest = "AndroidManifest.xml",
+ manifest_values = {"minSdkVersion": "15"},
+ resource_files = glob(["res/**"]),
+ test_class = "com.starlark_resources.SampleTest",
+ deps = [
+ "@robolectric//bazel:android-all",
+ "@rules_android_maven//:androidx_test_core",
+ "@rules_android_maven//:androidx_test_ext_junit",
+ "@rules_android_maven//:junit_junit",
+ "@rules_android_maven//:org_robolectric_robolectric",
+ ],
+)
+
+android_local_test(
+ name = "manifest_values_low_minsdk_no_manifest",
+ srcs = ["SampleTest.java"],
+ manifest_values = {"minSdkVersion": "15"},
+ resource_files = glob(["res/**"]),
+ test_class = "com.starlark_resources.SampleTest",
+ deps = [
+ "@robolectric//bazel:android-all",
+ "@rules_android_maven//:androidx_test_core",
+ "@rules_android_maven//:androidx_test_ext_junit",
+ "@rules_android_maven//:junit_junit",
+ "@rules_android_maven//:org_robolectric_robolectric",
+ ],
+)
diff --git a/test/rules/android_local_test/java/com/starlark_resources/SampleTest.java b/test/rules/android_local_test/java/com/starlark_resources/SampleTest.java
new file mode 100644
index 0000000..32529df
--- /dev/null
+++ b/test/rules/android_local_test/java/com/starlark_resources/SampleTest.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright 2021 The Bazel Authors. All rights reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.starlark_resources;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.content.res.Resources;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class SampleTest {
+ private Context targetContext;
+ private Resources resources;
+
+ @Before
+ public void setup() throws Exception {
+ targetContext = ApplicationProvider.getApplicationContext();
+ resources = targetContext.getResources();
+ }
+
+ @Test
+ public void test() throws Exception {
+ assertEquals("Check package name", "com.starlark_resources", targetContext.getPackageName());
+ assertEquals(
+ "Check resource `a_string`", "Hello World!", resources.getString(R.string.a_string));
+ }
+}
diff --git a/test/rules/android_local_test/java/com/starlark_resources/SampleTestMultipleDeps.java b/test/rules/android_local_test/java/com/starlark_resources/SampleTestMultipleDeps.java
new file mode 100644
index 0000000..7091594
--- /dev/null
+++ b/test/rules/android_local_test/java/com/starlark_resources/SampleTestMultipleDeps.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright 2021 The Bazel Authors. All rights reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.starlark_resources;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.content.res.Resources;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class SampleTestMultipleDeps {
+ private Context targetContext;
+ private Resources resources;
+
+ @Before
+ public void setup() throws Exception {
+ targetContext = ApplicationProvider.getApplicationContext();
+ resources = targetContext.getResources();
+ }
+
+ @Test
+ public void test() throws Exception {
+ assertEquals("Check package name", "com.starlark_resources", targetContext.getPackageName());
+ assertEquals(
+ "Check resource `a_string`", "Hello World!", resources.getString(R.string.a_string));
+ assertEquals(
+ "Check resource `another_res`", "Another Res!", resources.getString(R.string.another_res));
+ }
+}
diff --git a/test/rules/android_local_test/java/com/starlark_resources/SampleTestNeverlinkDep.java b/test/rules/android_local_test/java/com/starlark_resources/SampleTestNeverlinkDep.java
new file mode 100644
index 0000000..3da5dca
--- /dev/null
+++ b/test/rules/android_local_test/java/com/starlark_resources/SampleTestNeverlinkDep.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2021 The Bazel Authors. All rights reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.starlark_resources;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.content.res.Resources;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class SampleTestNeverlinkDep {
+ private Context targetContext;
+ private Resources resources;
+
+ @Before
+ public void setup() throws Exception {
+ targetContext = ApplicationProvider.getApplicationContext();
+ resources = targetContext.getResources();
+ }
+
+ @Test
+ public void test() throws Exception {
+ assertEquals("Check package name", "com.starlark_resources", targetContext.getPackageName());
+ try {
+ // This line should throw an exception since there are no resources inherited from
+ // neverlink deps.
+ assertEquals(
+ "Check resource `a_string`", "Hello World!", resources.getString(R.string.a_string));
+ } catch(NoClassDefFoundError e) {
+ return;
+ }
+ fail("Expected NoClassDefFoundError exception");
+ }
+}
diff --git a/test/rules/android_local_test/java/com/starlark_resources/another_res/values/strings.xml b/test/rules/android_local_test/java/com/starlark_resources/another_res/values/strings.xml
new file mode 100644
index 0000000..554ea5e
--- /dev/null
+++ b/test/rules/android_local_test/java/com/starlark_resources/another_res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="another_res">Another Res!</string>
+</resources>
diff --git a/test/rules/android_local_test/java/com/starlark_resources/assets/bar.txt b/test/rules/android_local_test/java/com/starlark_resources/assets/bar.txt
new file mode 100644
index 0000000..5716ca5
--- /dev/null
+++ b/test/rules/android_local_test/java/com/starlark_resources/assets/bar.txt
@@ -0,0 +1 @@
+bar
diff --git a/test/rules/android_local_test/java/com/starlark_resources/assets/foo.txt b/test/rules/android_local_test/java/com/starlark_resources/assets/foo.txt
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/test/rules/android_local_test/java/com/starlark_resources/assets/foo.txt
@@ -0,0 +1 @@
+foo
diff --git a/test/rules/android_local_test/java/com/starlark_resources/res/values/strings.xml b/test/rules/android_local_test/java/com/starlark_resources/res/values/strings.xml
new file mode 100644
index 0000000..2686d09
--- /dev/null
+++ b/test/rules/android_local_test/java/com/starlark_resources/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="a_string">Hello World!</string>
+</resources>
diff --git a/test/rules/android_local_test/java_launcher_integration_test.bzl b/test/rules/android_local_test/java_launcher_integration_test.bzl
new file mode 100644
index 0000000..a09a566
--- /dev/null
+++ b/test/rules/android_local_test/java_launcher_integration_test.bzl
@@ -0,0 +1,64 @@
+# Copyright 2021 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+""" Bazel rules that test the Android Local Test rule.
+
+launcher_test: Asserts that the executable is populated correctly in the target script.
+"""
+
+def _android_local_test_launcher_integration(ctx):
+ substitutions = {
+ "%executable%": ctx.attr.target[DefaultInfo].files_to_run.executable.short_path,
+ "%expected_executable%": ctx.attr.expected_executable,
+ }
+ runner = ctx.actions.declare_file(ctx.label.name + "_runner.sh")
+ ctx.actions.expand_template(
+ template = ctx.file._test_stub_script,
+ substitutions = substitutions,
+ output = runner,
+ )
+ return [
+ DefaultInfo(
+ executable = runner,
+ runfiles = ctx.runfiles(
+ files = [ctx.attr.target[DefaultInfo].files_to_run.executable],
+ ),
+ ),
+ ]
+
+integration_test = rule(
+ attrs = dict(
+ target = attr.label(),
+ _test_stub_script = attr.label(
+ cfg = "exec",
+ default = ":integration_test_stub_script.sh",
+ allow_single_file = True,
+ ),
+ expected_executable = attr.string(),
+ ),
+ test = True,
+ implementation = _android_local_test_launcher_integration,
+)
+
+def android_local_test_launcher_integration_test_suite(name, expected_executable):
+ integration_test(
+ name = "android_local_test_default_launcher_integration",
+ target = ":sample_test_default_launcher_integration",
+ expected_executable = expected_executable,
+ )
+
+ native.test_suite(
+ name = name,
+ tests = [":android_local_test_default_launcher_integration"],
+ )
diff --git a/test/rules/android_local_test/java_launcher_test.bzl b/test/rules/android_local_test/java_launcher_test.bzl
new file mode 100644
index 0000000..36d90fe
--- /dev/null
+++ b/test/rules/android_local_test/java_launcher_test.bzl
@@ -0,0 +1,50 @@
+# Copyright 2021 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+""" Bazel rules that test the Android Local Test rule.
+
+launcher_test: Asserts that the executable is contained in the target's runfiles.
+"""
+
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load("@bazel_skylib//lib:sets.bzl", "sets")
+
+def _android_local_test_default_launcher(ctx):
+ env = analysistest.begin(ctx)
+ target_under_test = analysistest.target_under_test(env)
+ expected_runfile = getattr(env.ctx.attr, "expected_runfile")
+
+ runfiles = sets.make([f.short_path for f in target_under_test[DefaultInfo].default_runfiles.files.to_list()])
+ asserts.true(env, sets.contains(runfiles, expected_runfile), "Expect runfiles to contains {0}".format(expected_runfile))
+
+ return analysistest.end(env)
+
+android_local_test_default_launcher_test = analysistest.make(
+ _android_local_test_default_launcher,
+ attrs = {
+ "expected_runfile": attr.string(),
+ },
+)
+
+def android_local_test_launcher_test_suite(name, expected_executable):
+ android_local_test_default_launcher_test(
+ name = "android_local_test_default_launcher",
+ target_under_test = ":sample_test_default_launcher",
+ expected_runfile = expected_executable,
+ )
+
+ native.test_suite(
+ name = name,
+ tests = [":android_local_test_default_launcher"],
+ )
diff --git a/test/rules/android_local_test/non_java/AndroidManifest.xml b/test/rules/android_local_test/non_java/AndroidManifest.xml
new file mode 100644
index 0000000..978e2c8
--- /dev/null
+++ b/test/rules/android_local_test/non_java/AndroidManifest.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.starlark_resources">
+ <uses-sdk
+ android:minSdkVersion="21"
+ android:targetSdkVersion="24" />
+</manifest>
diff --git a/test/rules/android_local_test/non_java/BUILD b/test/rules/android_local_test/non_java/BUILD
new file mode 100644
index 0000000..e3f10b7
--- /dev/null
+++ b/test/rules/android_local_test/non_java/BUILD
@@ -0,0 +1,51 @@
+# Tests that run on head android_local_test rule to verify Starlark resource processing pipeline.
+
+load(
+ "//rules:rules.bzl",
+ "android_library",
+ "android_local_test",
+)
+load(
+ "//test/rules/android_local_test:test.bzl",
+ "rule_test",
+)
+
+package(
+ default_applicable_licenses = ["//:license"],
+ default_visibility = ["//visibility:private"],
+)
+
+licenses(["notice"])
+
+android_library(
+ name = "resource_processing",
+ assets = ["assets/bar.txt"],
+ assets_dir = "assets",
+ custom_package = "com.starlark_resources",
+ manifest = "AndroidManifest.xml",
+ resource_files = glob(["res/**"]),
+)
+
+# A custom package is necessary when an android_local_test is under a non-java directory.
+android_local_test(
+ name = "with_custom_package",
+ srcs = ["SampleTest.java"],
+ custom_package = "com.starlark_resources",
+ manifest = "AndroidManifest.xml",
+ test_class = "com.starlark_resources.SampleTest",
+ deps = [
+ ":resource_processing",
+ "@robolectric//bazel:android-all",
+ "@rules_android_maven//:androidx_test_core",
+ "@rules_android_maven//:androidx_test_ext_junit",
+ "@rules_android_maven//:junit_junit",
+ "@rules_android_maven//:org_robolectric_robolectric",
+ ],
+)
+
+rule_test(
+ name = "with_custom_package_rule_test",
+ target_under_test = ":with_custom_package",
+)
+
+# TODO(b/161359429): Create failure test for missing custom package under a non-java directory.
diff --git a/test/rules/android_local_test/non_java/SampleTest.java b/test/rules/android_local_test/non_java/SampleTest.java
new file mode 100644
index 0000000..32529df
--- /dev/null
+++ b/test/rules/android_local_test/non_java/SampleTest.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright 2021 The Bazel Authors. All rights reserved.
+ *
+ * <p>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
+ *
+ * <p>http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * <p>Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.starlark_resources;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.content.res.Resources;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class SampleTest {
+ private Context targetContext;
+ private Resources resources;
+
+ @Before
+ public void setup() throws Exception {
+ targetContext = ApplicationProvider.getApplicationContext();
+ resources = targetContext.getResources();
+ }
+
+ @Test
+ public void test() throws Exception {
+ assertEquals("Check package name", "com.starlark_resources", targetContext.getPackageName());
+ assertEquals(
+ "Check resource `a_string`", "Hello World!", resources.getString(R.string.a_string));
+ }
+}
diff --git a/test/rules/android_local_test/non_java/assets/bar.txt b/test/rules/android_local_test/non_java/assets/bar.txt
new file mode 100644
index 0000000..5716ca5
--- /dev/null
+++ b/test/rules/android_local_test/non_java/assets/bar.txt
@@ -0,0 +1 @@
+bar
diff --git a/test/rules/android_local_test/non_java/res/values/strings.xml b/test/rules/android_local_test/non_java/res/values/strings.xml
new file mode 100644
index 0000000..2686d09
--- /dev/null
+++ b/test/rules/android_local_test/non_java/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="a_string">Hello World!</string>
+</resources>
diff --git a/test/rules/android_local_test/test.bzl b/test/rules/android_local_test/test.bzl
new file mode 100644
index 0000000..5b1677e
--- /dev/null
+++ b/test/rules/android_local_test/test.bzl
@@ -0,0 +1,117 @@
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# 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.
+
+"""Bazel rules that test the Android Local Test rule.
+
+rule_test: Inspect and assert on rule providers.
+"""
+
+load("//rules:providers.bzl", "AndroidFilteredJdepsInfo")
+load("//test/utils:asserts.bzl", "asserts")
+
+VALIDATION = "_validation"
+
+def _rule_test_impl(ctx):
+ # Assert on expected providers
+ if not JavaInfo in ctx.attr.target_under_test:
+ fail("Missing JavaInfo provider")
+ if not AndroidFilteredJdepsInfo in ctx.attr.target_under_test:
+ fail("Missing AndroidFilteredJdepsInfo provider")
+
+ # Collecting validation outputs from deps
+ transitive_validation_outputs = []
+ for dep in ctx.attr.deps:
+ if hasattr(dep[OutputGroupInfo], VALIDATION):
+ transitive_validation_outputs.append(dep[OutputGroupInfo]._validation)
+
+ output_group_info = dict(ctx.attr.expected_output_group_info)
+ if VALIDATION in output_group_info:
+ output_group_info[VALIDATION] = (
+ output_group_info[VALIDATION] +
+ [f.basename for f in depset(transitive = transitive_validation_outputs).to_list()]
+ )
+ asserts.provider.output_group_info(
+ output_group_info,
+ ctx.attr.target_under_test[OutputGroupInfo],
+ )
+
+ # Create test script to assert on provider contents
+ args = dict(
+ jdeps_print_tool = ctx.executable._jdeps_print_tool.short_path,
+ jdeps = ctx.attr.target_under_test[JavaInfo].outputs.jdeps.short_path,
+ filtered_jdeps = ctx.attr.target_under_test[AndroidFilteredJdepsInfo].jdeps.short_path,
+ res_jar = ctx.attr.target_under_test.label.name + "_resources.jar",
+ expect_resources = str(ctx.attr.expect_resources),
+ )
+ test_script = ctx.actions.declare_file("%s_script.sh" % ctx.label.name)
+ ctx.actions.write(
+ test_script,
+ """
+jdeps=`{jdeps_print_tool} --in {jdeps} | sed 's#_migrated/##g'`
+filtered_jdeps=`{jdeps_print_tool} --in {filtered_jdeps} | sed 's#_migrated/##g'`
+
+entries=`echo "$jdeps" | wc -l`
+matches=`echo "$jdeps" | grep '{res_jar}' | wc -l`
+filtered_entries=`echo "$filtered_jdeps" | wc -l`
+filtered_matches=`echo "$filtered_jdeps" | grep '{res_jar}' | wc -l`
+
+expected_matches=1
+expected_filtering_differences=1
+if [ {expect_resources} == "False" ]; then
+ expected_matches=0
+ expected_filtering_differences=0
+fi
+
+if [ $matches -ne $expected_matches ]; then
+ echo "Expected one resource.jar in jdeps"
+ exit 1
+elif [ $filtered_matches -ne 0 ]; then
+ echo "Expected no resource.jar in filtered jdeps"
+ exit 1
+elif [ $(($entries-$filtered_entries)) -ne $expected_filtering_differences ]; then
+ echo "Expected to remove one item when filtering"
+ exit 1
+fi
+""".format(**args),
+ is_executable = True,
+ )
+ return [
+ DefaultInfo(
+ runfiles = ctx.runfiles(
+ files = [
+ test_script,
+ ctx.executable._jdeps_print_tool,
+ ctx.attr.target_under_test[JavaInfo].outputs.jdeps,
+ ctx.attr.target_under_test[AndroidFilteredJdepsInfo].jdeps,
+ ],
+ ),
+ executable = test_script,
+ ),
+ ]
+
+rule_test = rule(
+ attrs = dict(
+ asserts.provider.attrs.items(),
+ expect_resources = attr.bool(default = True),
+ target_under_test = attr.label(),
+ deps = attr.label_list(),
+ _jdeps_print_tool = attr.label(
+ cfg = "exec",
+ default = "//src/tools/jdeps:print_jdeps",
+ executable = True,
+ ),
+ ),
+ implementation = _rule_test_impl,
+ test = True,
+)
diff --git a/test/rules/android_sdk_repository/test_lib.sh b/test/rules/android_sdk_repository/test_lib.sh
index 17d2485..a5abbba 100644
--- a/test/rules/android_sdk_repository/test_lib.sh
+++ b/test/rules/android_sdk_repository/test_lib.sh
@@ -33,6 +33,21 @@ source "$(rlocation rules_android/test/rules/android_sdk_repository/android_help
# Actual tests for Android Sdk Repository
+# Test that the dummy SDK exists.
+function test_dummy_sdk() {
+ # Create android SDK
+ local sdk_path="$(create_android_sdk_basic)"
+
+ cat >> WORKSPACE <<EOF
+android_sdk_repository(
+ name = "androidsdk",
+ path = "${sdk_path}",
+)
+EOF
+
+ "${BIT_BAZEL_BINARY}" query @androidsdk//:sdk-dummy >& $TEST_log || fail "Dummy SDK missing"
+}
+
# Check that the empty BUILD file was created.
function test_android_sdk_repository_no_path_or_android_home() {
cat >> WORKSPACE <<EOF
diff --git a/toolchains/android/toolchain.bzl b/toolchains/android/toolchain.bzl
index 2d067ac..04e7608 100644
--- a/toolchains/android/toolchain.bzl
+++ b/toolchains/android/toolchain.bzl
@@ -17,6 +17,7 @@
_ATTRS = dict(
aapt2 = attr.label(
allow_files = True,
+ cfg = "exec",
default = "@androidsdk//:aapt2_binary",
),
aar_import_checks = attr.label(
diff --git a/tools/android/BUILD b/tools/android/BUILD
index 922e7e3..2d323aa 100644
--- a/tools/android/BUILD
+++ b/tools/android/BUILD
@@ -17,6 +17,7 @@ genrule(
outs = ["fail.sh"],
cmd = "echo 'exit 1' > $@",
executable = 1,
+ visibility = ["//visibility:public"],
)
sh_binary(
@@ -43,7 +44,7 @@ java_plugin(
alias(
name = "java8_legacy_dex",
- actual = "@bazel_tools//tools/android:java8_legacy_dex",
+ actual = ":gen_fail",
visibility = ["//visibility:public"],
)
@@ -55,11 +56,19 @@ alias(
alias(
name = "desugared_java8_legacy_apis",
- actual = "@bazel_tools//tools/android:desugared_java8_legacy_apis",
+ actual = ":gen_fail", # TODO(#122): Fix library desugaring
visibility = ["//visibility:public"],
)
java_binary(
+ name = "d8",
+ main_class = "com.android.tools.r8.D8",
+ visibility = ["//visibility:public"],
+ runtime_deps = ["@android_gmaven_r8//jar"],
+)
+
+
+java_binary(
name = "r8",
main_class = "com.android.tools.r8.R8",
visibility = ["//visibility:public"],