1# Copyright 2023 The Bazel Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#    http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Rule for creating an Android Sandboxed SDK Bundle (ASB)."""
16
17load(":providers.bzl", "AndroidSandboxedSdkBundleInfo", "AndroidSandboxedSdkInfo")
18load(
19    "//rules:aapt.bzl",
20    _aapt = "aapt",
21)
22load(
23    "//rules:bundletool.bzl",
24    _bundletool = "bundletool",
25)
26load(
27    "//rules:common.bzl",
28    _common = "common",
29)
30load(
31    "//rules:utils.bzl",
32    _get_android_toolchain = "get_android_toolchain",
33)
34
35_ATTRS = dict(
36    sdk = attr.label(
37        providers = [
38            [AndroidSandboxedSdkInfo],
39        ],
40    ),
41    _host_javabase = attr.label(
42        cfg = "exec",
43        default = Label("//tools/jdk:current_java_runtime"),
44    ),
45)
46
47def _impl(ctx):
48    host_javabase = _common.get_host_javabase(ctx)
49
50    # Convert internal APK to proto resources.
51    internal_proto_apk = ctx.actions.declare_file(ctx.label.name + "_internal_proto_apk")
52    _aapt.convert(
53        ctx,
54        out = internal_proto_apk,
55        input = ctx.attr.sdk[AndroidSandboxedSdkInfo].internal_apk_info.unsigned_apk,
56        to_proto = True,
57        aapt = _get_android_toolchain(ctx).aapt2.files_to_run,
58    )
59
60    # Invoke module builder to create a base.zip that bundletool accepts.
61    module_zip = ctx.actions.declare_file(ctx.label.name + "_module.zip")
62    _bundletool.build_sdk_module(
63        ctx,
64        out = module_zip,
65        internal_apk = internal_proto_apk,
66        bundletool_module_builder =
67            _get_android_toolchain(ctx).bundletool_module_builder.files_to_run,
68        host_javabase = host_javabase,
69    )
70
71    # Invoke bundletool and create the bundle.
72    _bundletool.build_sdk_bundle(
73        ctx,
74        out = ctx.outputs.asb,
75        module = module_zip,
76        sdk_api_descriptors = ctx.attr.sdk[AndroidSandboxedSdkInfo].sdk_api_descriptors,
77        sdk_modules_config = ctx.attr.sdk[AndroidSandboxedSdkInfo].sdk_module_config,
78        bundletool = _get_android_toolchain(ctx).bundletool.files_to_run,
79        host_javabase = host_javabase,
80    )
81
82    return [
83        AndroidSandboxedSdkBundleInfo(
84            asb = ctx.outputs.asb,
85            sdk_info = ctx.attr.sdk[AndroidSandboxedSdkInfo],
86        ),
87    ]
88
89android_sandboxed_sdk_bundle = rule(
90    attrs = _ATTRS,
91    executable = False,
92    implementation = _impl,
93    provides = [
94        AndroidSandboxedSdkBundleInfo,
95    ],
96    outputs = {
97        "asb": "%{name}.asb",
98    },
99    toolchains = [
100        "//toolchains/android:toolchain_type",
101        "//toolchains/android_sdk:toolchain_type",
102        "@bazel_tools//tools/jdk:toolchain_type",
103    ],
104    fragments = ["android"],
105)
106