diff --git a/.bazelversion b/.bazelversion index 798e38995..eab246c06 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -6.3.0 +7.3.2 diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 000000000..90ca30525 --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,174 @@ +module(name = "android_test_support") + +bazel_dep(name = "rules_android", version = "0.5.1") +bazel_dep(name = "rules_java", version = "7.12.1") +bazel_dep(name = "rules_jvm_external", version = "6.4") +bazel_dep(name = "rules_license", version = "1.0.0") +bazel_dep(name = "rules_kotlin", version = "2.0.0") +bazel_dep(name = "rules_proto", version = "6.0.2") +bazel_dep(name = "rules_robolectric", version = "4.13") +bazel_dep(name = "grpc-java", version = "1.66.0") +bazel_dep(name = "abseil-py", version = "2.1.0") + +# These need to be consistent with their counterparts in build_extensions/axt_deps_versions.bzl. +KOTLIN_VERSION = "1.8.20" +KOTLINX_COROUTINES_VERSION = "1.7.1" +GRPC_VERSION = "1.66.0" + +maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") + +load( + "//build_extensions:axt_deps_versions.bzl", + "ANDROIDX_ANNOTATION_EXPERIMENTAL_VERSION", + "ANDROIDX_ANNOTATION_VERSION", + "ANDROIDX_COMPAT_VERSION", + "ANDROIDX_CONCURRENT_VERSION", + "ANDROIDX_CORE_VERSION", + "ANDROIDX_CURSOR_ADAPTER_VERSION", + "ANDROIDX_DRAWER_LAYOUT_VERSION", + "ANDROIDX_FRAGMENT_VERSION", + "ANDROIDX_LEGACY_SUPPORT_VERSION", + "ANDROIDX_LIFECYCLE_VERSION", + "ANDROIDX_MULTIDEX_VERSION", + "ANDROIDX_RECYCLERVIEW_VERSION", + "ANDROIDX_TRACING_VERSION", + "ANDROIDX_VIEWPAGER_VERSION", + "ANDROIDX_WINDOW_VERSION", + "GOOGLE_MATERIAL_VERSION", + "GUAVA_LISTENABLEFUTURE_VERSION", + "GUAVA_VERSION", + "JUNIT_VERSION", + "UIAUTOMATOR_VERSION", + "ATF_VERSION" +) + +maven.install( + name = "maven", + artifacts = [ + "androidx.annotation:annotation:" + ANDROIDX_ANNOTATION_VERSION, + "androidx.annotation:annotation-experimental:jar:" + ANDROIDX_ANNOTATION_EXPERIMENTAL_VERSION, + "androidx.appcompat:appcompat:" + ANDROIDX_COMPAT_VERSION, + "androidx.concurrent:concurrent-futures:" + ANDROIDX_CONCURRENT_VERSION, + "androidx.concurrent:concurrent-futures-ktx:" + ANDROIDX_CONCURRENT_VERSION, + "androidx.core:core:" + ANDROIDX_CORE_VERSION, + "androidx.cursoradapter:cursoradapter:" + ANDROIDX_CURSOR_ADAPTER_VERSION, + "androidx.drawerlayout:drawerlayout:" + ANDROIDX_DRAWER_LAYOUT_VERSION, + "androidx.fragment:fragment:" + ANDROIDX_FRAGMENT_VERSION, + "androidx.legacy:legacy-support-core-ui:" + ANDROIDX_LEGACY_SUPPORT_VERSION, + "androidx.legacy:legacy-support-core-utils:" + ANDROIDX_LEGACY_SUPPORT_VERSION, + "androidx.legacy:legacy-support-v4:" + ANDROIDX_LEGACY_SUPPORT_VERSION, + "androidx.lifecycle:lifecycle-common:" + ANDROIDX_LIFECYCLE_VERSION, + "androidx.multidex:multidex:" + ANDROIDX_MULTIDEX_VERSION, + "androidx.recyclerview:recyclerview:" + ANDROIDX_RECYCLERVIEW_VERSION, + "androidx.tracing:tracing:" + ANDROIDX_TRACING_VERSION, + "androidx.test.uiautomator:uiautomator:" + UIAUTOMATOR_VERSION, + "androidx.viewpager:viewpager:" + ANDROIDX_VIEWPAGER_VERSION, + "androidx.window:window:" + ANDROIDX_WINDOW_VERSION, + "androidx.window:window-java:" + ANDROIDX_WINDOW_VERSION, + "androidx.window:window-core:" + ANDROIDX_WINDOW_VERSION, + "aopalliance:aopalliance:1.0", + "com.android.tools.lint:lint-api:30.1.0", + "com.android.tools.lint:lint-checks:30.1.0", + "com.beust:jcommander:1.72", + maven.artifact( + artifact = "accessibility-test-framework", + exclusions = [ + # exclude the org.checkerframework dependency since that require + # java8 compatibility. See b/176926990 + maven.exclusion( + artifact = "checker", + group = "org.checkerframework", + ), + # accessibility-test-framework depends on hamcrest 2.2 which causes 'Using type org.hamcrest.Matcher from an indirect dependency' compile errors + maven.exclusion( + artifact = "hamcrest-core", + group = "org.hamcrest", + ), + maven.exclusion( + artifact = "hamcrest-library", + group = "org.hamcrest", + ), + ], + group = "com.google.android.apps.common.testing.accessibility.framework", + version = ATF_VERSION, + ), + "com.google.android.material:material:" + GOOGLE_MATERIAL_VERSION, + "com.google.auto.value:auto-value:1.5.1", + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.code.gson:gson:2.8.5", + "com.google.dagger:dagger-compiler:2.46", + "com.google.dagger:dagger-producers:2.46", + "com.google.dagger:dagger:2.46", + "com.google.errorprone:error_prone_annotations:2.9.0", + "com.google.errorprone:javac-shaded:9-dev-r4023-3", + "com.google.flogger:flogger-system-backend:0.4", + "com.google.flogger:flogger:0.4", + "com.google.flogger:google-extensions:0.4", + "com.google.googlejavaformat:google-java-format:1.4", + "com.google.guava:guava:" + GUAVA_VERSION, + "com.google.guava:listenablefuture:" + GUAVA_LISTENABLEFUTURE_VERSION, + "com.google.inject.extensions:guice-multibindings:4.1.0", + "com.google.inject:guice:4.1.0", + "com.google.truth:truth:1.0", + "com.googlecode.jarjar:jarjar:1.3", + "com.linkedin.dexmaker:dexmaker-mockito:jar:2.28.1", + "com.linkedin.dexmaker:dexmaker:2.28.1", + "org.mockito.kotlin:mockito-kotlin:4.1.0", + "com.squareup:javapoet:1.9.0", + "io.grpc:grpc-okhttp:1.54.1", + "io.grpc:grpc-stub:1.54.1", + "org.apache.tomcat:annotations-api:6.0.53", + "javax.annotation:javax.annotation-api:1.3.1", + "javax.inject:javax.inject:1", + "joda-time:joda-time:2.10.1", + "junit:junit:" + JUNIT_VERSION, + "net.bytebuddy:byte-buddy-agent:1.9.10", + "net.bytebuddy:byte-buddy:1.9.10", + "net.sf.kxml:kxml2:jar:2.3.0", + "org.ccil.cowan.tagsoup:tagsoup:1.2.1", + "org.checkerframework:checker-compat-qual:2.5.5", + "org.hamcrest:hamcrest-core:1.3", + "org.hamcrest:hamcrest-library:1.3", + "org.mockito:mockito-core:2.28.1", + "org.objenesis:objenesis:2.6", + "org.pantsbuild:jarjar:1.7.2", + "org.jetbrains.kotlin:kotlin-stdlib:%s" % KOTLIN_VERSION, + "org.jetbrains.kotlinx:kotlinx-coroutines-core:%s" % KOTLINX_COROUTINES_VERSION, + "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:%s" % KOTLINX_COROUTINES_VERSION, + "org.jetbrains.kotlinx:kotlinx-coroutines-android:%s" % KOTLINX_COROUTINES_VERSION, + maven.artifact( + artifact = "robolectric", + exclusions = [ + # exclude the com.google.guava dependency since that require + # java8 compatibility. + maven.exclusion( + artifact = "guava", + group = "com.google.guava", + ), + ], + group = "org.robolectric", + version = "4.13", + ), + ], + fetch_sources = True, + generate_compat_repositories = True, + repositories = [ + "https://maven.google.com", + "https://repo1.maven.org/maven2", + "https://dl.bintray.com/linkedin/maven", + ], +) + +# need to have a isolated version tree for listenablefuture, because otherwise +# listenablefuture will get resolved to 9999.0-empty-to-avoid-conflict-with-guava +maven.install( + name = "maven_listenablefuture", + artifacts = [ + "com.google.guava:listenablefuture:" + GUAVA_LISTENABLEFUTURE_VERSION, + ], + repositories = [ + "https://maven.google.com", + "https://repo1.maven.org/maven2", + "https://dl.bintray.com/linkedin/maven", + ], +) \ No newline at end of file diff --git a/WORKSPACE b/WORKSPACE index 0f20ad0b8..151eb33ad 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -31,14 +31,18 @@ http_archive( # rules_proto defines proto_library, as well as @com_google_protobuf_javalite http_archive( name = "rules_proto", - sha256 = "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd", - strip_prefix = "rules_proto-5.3.0-21.7", - urls = [ - "https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz", - ], + sha256 = "6fb6767d1bef535310547e03247f7518b03487740c11b6c6adb7952033fe1295", + strip_prefix = "rules_proto-6.0.2", + url = "https://github.com/bazelbuild/rules_proto/releases/download/6.0.2/rules_proto-6.0.2.tar.gz", ) -load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains") + +load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies") rules_proto_dependencies() + +load("@rules_proto//proto:setup.bzl", "rules_proto_setup") +rules_proto_setup() + +load("@rules_proto//proto:toolchains.bzl", "rules_proto_toolchains") rules_proto_toolchains() load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") @@ -229,16 +233,13 @@ robolectric_repositories() # Kotlin toolchains -rules_kotlin_version = "1.8-RC-12" -rules_kotlin_sha = "8e5c8ab087e0fa3fbb58e1f6b99d8fe40f75bac44994c3d208eba723284465d6" - http_archive( - name = "io_bazel_rules_kotlin", - sha256 = rules_kotlin_sha, - urls = ["https://github.com/bazelbuild/rules_kotlin/releases/download/v%s/rules_kotlin_release.tgz" % rules_kotlin_version], + name = "rules_kotlin", + sha256 = "d89723cc9ebbb7bdb2ebaca1af7d2383e074615643cf97a366b758a76b7dc443", + url = "https://github.com/bazelbuild/rules_kotlin/releases/download/v2.0.0/rules_kotlin-v2.0.0.tar.gz", ) -load("@io_bazel_rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories", "kotlinc_version") +load("@rules_kotlin//kotlin:repositories.bzl", "kotlin_repositories", "kotlinc_version") kotlin_repositories( compiler_release = kotlinc_version( @@ -247,30 +248,26 @@ kotlin_repositories( ), ) -load("@io_bazel_rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") +load("@rules_kotlin//kotlin:core.bzl", "kt_register_toolchains") kt_register_toolchains() -# Android bazel rules from Dec 22 2022. This is the last commit that supports bazel 6.0.0 -RULES_ANDROID_COMMIT = "ce37817d8589cac4a7cc20cb4d51fe8ad459dea1" - -RULES_ANDROID_SHA = "402b1ed3756028dca11835dad3225689a4040c3b377de798709f9a39b5c6af17" - http_archive( name = "rules_android", - sha256 = RULES_ANDROID_SHA, - strip_prefix = "rules_android-%s" % RULES_ANDROID_COMMIT, - url = "https://github.com/bazelbuild/rules_android/archive/%s.zip" % RULES_ANDROID_COMMIT, + sha256 = "b1599e4604c1594a1b0754184c5e50f895a68f444d1a5a82b688b2370d990ba0", + strip_prefix = "rules_android-0.5.1", + url = "https://github.com/bazelbuild/rules_android/releases/download/v0.5.1/rules_android-v0.5.1.tar.gz", ) - load("@rules_android//:prereqs.bzl", "rules_android_prereqs") - rules_android_prereqs() - load("@rules_android//:defs.bzl", "rules_android_workspace") - rules_android_workspace() +load("@rules_android//rules:rules.bzl", "android_sdk_repository") +android_sdk_repository( + name = "androidsdk", +) + register_toolchains( "@rules_android//toolchains/android:android_default_toolchain", "@rules_android//toolchains/android_sdk:android_sdk_tools", diff --git a/WORKSPACE.bzlmod b/WORKSPACE.bzlmod new file mode 100644 index 000000000..563ac03c1 --- /dev/null +++ b/WORKSPACE.bzlmod @@ -0,0 +1 @@ +workspace(name = "android_test_support") \ No newline at end of file diff --git a/build_extensions/axt_android_local_test.bzl b/build_extensions/axt_android_local_test.bzl index 9cef617ff..3e329943a 100644 --- a/build_extensions/axt_android_local_test.bzl +++ b/build_extensions/axt_android_local_test.bzl @@ -1,10 +1,10 @@ """A rule wrapper for generating android_local_test .""" -load("@io_bazel_rules_kotlin//kotlin:android.bzl", "kt_android_library") +load("@rules_kotlin//kotlin:android.bzl", "kt_android_library") _CONFIG_JAR_COMMAND = """ set -e -JAR="$(location @bazel_tools//tools/jdk:jar)" +JAR="$(location @local_jdk//:bin/jar)" SRC="$<" [[ "$$(basename "$${SRC}")" = 'robolectric.properties' ]] || { echo 'Must be named: robolectric.properties'; diff --git a/build_extensions/axt_deps_versions.bzl b/build_extensions/axt_deps_versions.bzl index d33b16aff..9db0aae03 100644 --- a/build_extensions/axt_deps_versions.bzl +++ b/build_extensions/axt_deps_versions.bzl @@ -25,7 +25,7 @@ JANK_VERSION = "1.0.1" # this should match the kotlin toolchain version eg bazel_rules/rules_kotlin/toolchains/kotlin_jvm/kt_jvm_toolchains.bzl KT_VERSION # and WORKSPACE:KOTLIN_VERSION KOTLIN_VERSION = "1.8.20" -GRPC_VERSION = "1.54.1" # needs to match WORKSPACE:GRPC_VERSION +GRPC_VERSION = "1.66.0" # needs to match WORKSPACE:GRPC_VERSION ATF_VERSION = "3.1.2" # accessibilitytestframework JUNIT_VERSION = "4.13.2" diff --git a/build_extensions/jar_combiner/java/androidx/test/tools/jarcombiner/BUILD b/build_extensions/jar_combiner/java/androidx/test/tools/jarcombiner/BUILD index 20a5bb87e..3640d927b 100644 --- a/build_extensions/jar_combiner/java/androidx/test/tools/jarcombiner/BUILD +++ b/build_extensions/jar_combiner/java/androidx/test/tools/jarcombiner/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") package( default_visibility = [ diff --git a/build_extensions/jar_combiner/javatests/androidx/test/tools/jarcombiner/BUILD b/build_extensions/jar_combiner/javatests/androidx/test/tools/jarcombiner/BUILD index ebe2f2346..aa97f5b81 100644 --- a/build_extensions/jar_combiner/javatests/androidx/test/tools/jarcombiner/BUILD +++ b/build_extensions/jar_combiner/javatests/androidx/test/tools/jarcombiner/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_test") +load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_test") kt_jvm_test( name = "JarCombinerTest", diff --git a/build_extensions/jar_validator/java/androidx/test/tools/jarvalidator/BUILD b/build_extensions/jar_validator/java/androidx/test/tools/jarvalidator/BUILD index f5517603c..f388ea134 100644 --- a/build_extensions/jar_validator/java/androidx/test/tools/jarvalidator/BUILD +++ b/build_extensions/jar_validator/java/androidx/test/tools/jarvalidator/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") kt_jvm_library( name = "jarvalidator_lib", diff --git a/build_extensions/jar_validator/javatests/androidx/test/tools/jarvalidator/BUILD b/build_extensions/jar_validator/javatests/androidx/test/tools/jarvalidator/BUILD index 53a4895cc..247b065bd 100644 --- a/build_extensions/jar_validator/javatests/androidx/test/tools/jarvalidator/BUILD +++ b/build_extensions/jar_validator/javatests/androidx/test/tools/jarvalidator/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_test") +load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_test") kt_jvm_test( name = "JarValidatorTest", diff --git a/build_extensions/kt_android_library.bzl b/build_extensions/kt_android_library.bzl index 5dad83b27..df01a5251 100644 --- a/build_extensions/kt_android_library.bzl +++ b/build_extensions/kt_android_library.bzl @@ -1,7 +1,7 @@ """Wrapper for android_library for bazel. """ -load("@io_bazel_rules_kotlin//kotlin:android.bzl", io_kt_android_library = "kt_android_library") +load("@rules_kotlin//kotlin:android.bzl", _kt_android_library = "kt_android_library") def kt_android_library(**kwargs): - io_kt_android_library(**kwargs) + _kt_android_library(**kwargs) diff --git a/build_extensions/maven/axt_android_aar.bzl b/build_extensions/maven/axt_android_aar.bzl index 6497a9894..6e72515e8 100644 --- a/build_extensions/maven/axt_android_aar.bzl +++ b/build_extensions/maven/axt_android_aar.bzl @@ -97,7 +97,7 @@ axt_android_aar = rule( default = ["com.google.guava:guava", "com.google.dagger"], ), "_jdk": attr.label( - default = Label("@bazel_tools//tools/jdk"), + default = Label("@local_jdk//:bin/java"), providers = [java_common.JavaRuntimeInfo], ), "_combine_jars_java": attr.label( diff --git a/build_extensions/maven/jarjar.bzl b/build_extensions/maven/jarjar.bzl index 80bffb9a4..c3f10b520 100644 --- a/build_extensions/maven/jarjar.bzl +++ b/build_extensions/maven/jarjar.bzl @@ -42,7 +42,7 @@ jarjar = rule( allow_single_file = [".txt"], ), "_jdk": attr.label( - default = Label("@bazel_tools//tools/jdk"), + default = Label("@local_jdk//:bin/java"), providers = [java_common.JavaRuntimeInfo], ), "_jarjar": attr.label( diff --git a/build_extensions/maven/kotlin_info.bzl b/build_extensions/maven/kotlin_info.bzl index f7e0a4141..a7e9f0110 100644 --- a/build_extensions/maven/kotlin_info.bzl +++ b/build_extensions/maven/kotlin_info.bzl @@ -1,6 +1,6 @@ """Utility for determing if given target is a kotlin target""" -load("@io_bazel_rules_kotlin//kotlin/internal:defs.bzl", "KtJvmInfo") +load("@rules_kotlin//kotlin/internal:defs.bzl", "KtJvmInfo") def is_kotlin(target): return KtJvmInfo in target diff --git a/build_extensions/maven/maven_artifact.bzl b/build_extensions/maven/maven_artifact.bzl index 6a38f74f4..35fa005fd 100644 --- a/build_extensions/maven/maven_artifact.bzl +++ b/build_extensions/maven/maven_artifact.bzl @@ -278,7 +278,7 @@ maven_artifact = rule( doc = "Map of maven dependency to a csv list of excluded dependencies. eg {\"com.google.foo:foo\":\"com.google.bar:bar,com.google.bar:bar-none\"}", ), "_jar": attr.label( - default = Label("@bazel_tools//tools/jdk:jar"), + default = Label("@local_jdk//:bin/jar"), executable = True, allow_files = True, cfg = "exec", diff --git a/build_extensions/zip_combiner/java/androidx/test/tools/zipcombiner/BUILD b/build_extensions/zip_combiner/java/androidx/test/tools/zipcombiner/BUILD index ba3024598..e6c7c0be7 100644 --- a/build_extensions/zip_combiner/java/androidx/test/tools/zipcombiner/BUILD +++ b/build_extensions/zip_combiner/java/androidx/test/tools/zipcombiner/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") +load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") package( default_visibility = [ diff --git a/repo.bzl b/repo.bzl index 526da15c9..4d862faee 100644 --- a/repo.bzl +++ b/repo.bzl @@ -124,10 +124,9 @@ def android_test_repositories(with_dev_repositories = False): # Protobuf http_archive( name = "com_google_protobuf", - sha256 = "d82eb0141ad18e98de47ed7ed415daabead6d5d1bef1b8cccb6aa4d108a9008f", - strip_prefix = "protobuf-b4f193788c9f0f05d7e0879ea96cd738630e5d51", - # Commit from 2019-05-15, update to protobuf 3.8 when available. - url = "https://github.com/protocolbuffers/protobuf/archive/b4f193788c9f0f05d7e0879ea96cd738630e5d51.tar.gz", + sha256 = "b2340aa47faf7ef10a0328190319d3f3bee1b24f426d4ce8f4253b6f27ce16db", + strip_prefix = "protobuf-28.2", + url = "https://github.com/protocolbuffers/protobuf/releases/download/v28.2/protobuf-28.2.tar.gz", ) # Protobuf's dependencies @@ -137,21 +136,24 @@ def android_test_repositories(with_dev_repositories = False): http_archive( name = "zlib", build_file = "@com_google_protobuf//:third_party/zlib.BUILD", - sha256 = "91844808532e5ce316b3c010929493c0244f3d37593afd6de04f71821d5136d9", - strip_prefix = "zlib-1.2.12", - urls = ["https://zlib.net/zlib-1.2.12.tar.gz"], + sha256 = "9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23", + strip_prefix = "zlib-1.3.1", + urls = ["https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz"], ) http_archive( name = "bazel_skylib", - url = "https://github.com/bazelbuild/bazel-skylib/releases/download/0.8.0/bazel-skylib.0.8.0.tar.gz", - sha256 = "2ef429f5d7ce7111263289644d233707dba35e39696377ebab8b0bc701f7818e", + sha256 = "bc283cdfcd526a52c3201279cda4bc298652efa898b10b4db0837dc51652756f", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz", + ], ) # Open source version of the google python flags library. http_archive( name = "absl_py", - sha256 = "980ce58c34dfa75a9d20d45c355658191c166557f1de41ab52f208bd00604c2b", - strip_prefix = "abseil-py-b347ba6022370f895d3133241ed96965b95ecb40", - urls = ["https://github.com/abseil/abseil-py/archive/b347ba6022370f895d3133241ed96965b95ecb40.tar.gz"], + sha256 = "8a3d0830e4eb4f66c4fa907c06edf6ce1c719ced811a12e26d9d3162f8471758", + strip_prefix = "abseil-py-2.1.0", + urls = ["https://github.com/abseil/abseil-py/archive/refs/tags/v2.1.0.tar.gz"], ) diff --git a/services/CHANGELOG.md b/services/CHANGELOG.md index 9d62f882d..09bed8125 100644 --- a/services/CHANGELOG.md +++ b/services/CHANGELOG.md @@ -11,6 +11,8 @@ **New Features** +* Added a new protocol to replace SpeakEasy. + **Breaking Changes** **API Changes** diff --git a/services/shellexecutor/java/androidx/test/services/shellexecutor/BUILD b/services/shellexecutor/java/androidx/test/services/shellexecutor/BUILD index c1257b98d..0d5eb54c9 100644 --- a/services/shellexecutor/java/androidx/test/services/shellexecutor/BUILD +++ b/services/shellexecutor/java/androidx/test/services/shellexecutor/BUILD @@ -29,6 +29,32 @@ kt_android_library( ], ) +proto_library( + name = "local_socket_protocol_pb", + srcs = ["local_socket_protocol.proto"], +) + +java_lite_proto_library( + name = "local_socket_protocol_pb_java_proto_lite", + visibility = [ + "//services/shellexecutor/javatests/androidx/test/services/shellexecutor:__subpackages__", + ], + deps = [":local_socket_protocol_pb"], +) + +kt_android_library( + name = "local_socket_protocol", + srcs = ["LocalSocketProtocol.kt"], + visibility = [ + "//services/shellexecutor/javatests/androidx/test/services/shellexecutor:__subpackages__", + ], + deps = [ + ":local_socket_protocol_pb_java_proto_lite", + "@com_google_protobuf//:protobuf_javalite", + "@maven//:org_jetbrains_kotlinx_kotlinx_coroutines_core", + ], +) + kt_android_library( name = "exec_server", srcs = [ diff --git a/services/shellexecutor/java/androidx/test/services/shellexecutor/LocalSocketProtocol.kt b/services/shellexecutor/java/androidx/test/services/shellexecutor/LocalSocketProtocol.kt new file mode 100644 index 000000000..c36dea437 --- /dev/null +++ b/services/shellexecutor/java/androidx/test/services/shellexecutor/LocalSocketProtocol.kt @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.test.services.shellexecutor + +import android.net.LocalSocket +import android.net.LocalSocketAddress +import android.util.Log +import androidx.test.services.shellexecutor.LocalSocketProtocolProto.RunCommandRequest +import androidx.test.services.shellexecutor.LocalSocketProtocolProto.RunCommandResponse +import com.google.protobuf.ByteString +import java.io.IOException +import java.net.URLDecoder +import java.net.URLEncoder +import kotlin.time.Duration + +/** + * Protocol for ShellCommandLocalSocketClient to talk to ShellCommandLocalSocketExecutorServer. + * + * Since androidx.test.services already includes the protobuf runtime, we aren't paying much extra + * for adding some more protos to ship back and forth, which is vastly easier to deal with than + * PersistableBundles (which don't even support ByteArray types). + * + * A conversation consists of a single RunCommandRequest from the client followed by a stream of + * RunCommandResponses from the server; the final response has an exit code. + */ +object LocalSocketProtocol { + /** Composes a RunCommandRequest and sends it over the LocalSocket. */ + fun LocalSocket.sendRequest( + argv: List, + env: Map? = null, + timeout: Duration, + ) { + val builder = RunCommandRequest.newBuilder() + builder.addAllArgv(argv) + env?.forEach { (k, v) -> builder.putEnvironment(k, v) } + builder.setTimeoutMs(timeout.inWholeMilliseconds) + builder.build().writeDelimitedTo(outputStream) + } + + /** Reads a RunCommandRequest from the LocalSocket. */ + fun LocalSocket.readRequest(): RunCommandRequest { + return RunCommandRequest.parseDelimitedFrom(inputStream)!! + } + + /** Composes a RunCommandResponse and sends it over the LocalSocket. */ + fun LocalSocket.sendResponse( + buffer: ByteArray? = null, + size: Int = 0, + exitCode: Int? = null, + ): Boolean { + val builder = RunCommandResponse.newBuilder() + buffer?.let { + val bufferSize = if (size > 0) size else it.size + builder.buffer = ByteString.copyFrom(it, 0, bufferSize) + } + exitCode?.let { builder.exitCode = it } + + try { + builder.build().writeDelimitedTo(outputStream) + } catch (x: IOException) { + // Sadly, the only way to discover that the client cut the connection is an exception that + // can only be distinguished by its text. + if (x.message.equals("Broken pipe")) { + Log.i(TAG, "LocalSocket stream closed early") + } else { + Log.w(TAG, "LocalSocket write failed", x) + } + return false + } + return true + } + + /** Reads a RunCommandResponse from the LocalSocket. */ + fun LocalSocket.readResponse(): RunCommandResponse? { + return RunCommandResponse.parseDelimitedFrom(inputStream) + } + + /** + * The address can contain spaces, and since it gets passed through a command line, we need to + * encode it so it doesn't get split by argv. java.net.URLEncoder is conveniently available on all + * SDK versions. + */ + @JvmStatic fun LocalSocketAddress.asBinderKey() = ":${URLEncoder.encode(name, "UTF-8")}" + + @JvmStatic + fun fromBinderKey(binderKey: String) = + LocalSocketAddress(URLDecoder.decode(binderKey.trimStart(':'), "UTF-8")) + + @JvmStatic fun isBinderKey(maybeKey: String) = maybeKey.startsWith(':') + + const val TAG = "LocalSocketProtocol" +} diff --git a/services/shellexecutor/java/androidx/test/services/shellexecutor/local_socket_protocol.proto b/services/shellexecutor/java/androidx/test/services/shellexecutor/local_socket_protocol.proto new file mode 100644 index 000000000..f92259694 --- /dev/null +++ b/services/shellexecutor/java/androidx/test/services/shellexecutor/local_socket_protocol.proto @@ -0,0 +1,36 @@ +// +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +edition = "2023"; +//syntax = "proto3"; // Maven on github doesn't like 'edition = "2023"' + +package androidx.test.services.storage; + +option java_package = "androidx.test.services.shellexecutor"; +option java_outer_classname = 'LocalSocketProtocolProto'; + +// Message sent from client to server to start a process. +message RunCommandRequest { + repeated string argv = 1; + map environment = 2; + int64 timeout_ms = 3; +} + +// Multiple responses can be streamed back to the client. The one that has an +// exit code indicates the end of the stream. +message RunCommandResponse { + bytes buffer = 1; + int32 exit_code = 2; +} diff --git a/tools/release/java/androidx/test/tools/releaseupdater/BUILD b/tools/release/java/androidx/test/tools/releaseupdater/BUILD index 5ddabc1ac..8dce6684b 100644 --- a/tools/release/java/androidx/test/tools/releaseupdater/BUILD +++ b/tools/release/java/androidx/test/tools/releaseupdater/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_binary", "kt_jvm_library") +load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_binary", "kt_jvm_library") package( default_visibility = [ diff --git a/tools/release/javatests/androidx/test/tools/releaseupdater/BUILD b/tools/release/javatests/androidx/test/tools/releaseupdater/BUILD index ede11f2ae..53c8ea9c1 100644 --- a/tools/release/javatests/androidx/test/tools/releaseupdater/BUILD +++ b/tools/release/javatests/androidx/test/tools/releaseupdater/BUILD @@ -1,4 +1,4 @@ -load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_test") +load("@rules_kotlin//kotlin:jvm.bzl", "kt_jvm_test") package( default_visibility = [